Can a List Comprehension do ____ ?

E

Eric @ Zomething

Pythonistas,

I seem at a loss for a List Comprehension syntax that will do what I want.

I have a list of string position spans:
[(133, 137), (181, 185), (227, 231), (232, 236), (278, 282), (283, 287), (352, 356), (412, 416), (485, 489), (490, 494)]

the first pair representing: someString[133:137]

What I want is a list of the positions between these spans, which would look like this:
[[(137, 181)], [(185, 227)], [(231, 232)], [(236, 278)], [(282, 283)], [(287, 352)], [(356, 412)], [(416, 485)], [(489, 490)]]


Of course I can get such a list, but I haven't been able to figure out how to do this with a List Comprehension. I am wondering if there is a syntax which makes pairs of the maximum of one list element and the minimum of the next list element.

Can anyone show me the List Comprehensions light?

Was trying things like this:
listSpans=[(max(x,y),min(a,b)) for (x,y) in breaks for (a,b) in breaks.pop()]




With regards



Eric Pederson
http://www.songzilla.blogspot.com
::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
e-mail me at:
(e-mail address removed)
except, increment the "d" and "o" by one letter
and spell something with a "z"
::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
 
P

Peter Otten

Eric said:
[(133, 137), (181, 185), (227, 231), (232, 236), (278, 282), (283, 287),
[(352, 356), (412, 416), (485, 489), (490, 494)]

the first pair representing: someString[133:137]

What I want is a list of the positions between these spans, which would
look like this:
[[(137, 181)], [(185, 227)], [(231, 232)], [(236, 278)], [(282, 283)],
[[[(287, 352)], [(356, 412)], [(416, 485)], [(489, 490)]]
breaks = [(133, 137), (181, 185), (227, 231), (232, 236), (278, 282), (283, 287), (352, 356), (412, 416), (485, 489), (490, 494)]
it = iter(breaks)
[(start, end) for ((_, start), (end, _)) in zip(it, it)] [(137, 181), (231, 232), (282, 283), (356, 412), (489, 490)]

Peter
 
R

Robin Becker

I want to use a list of glob patterns to create a single flat list of files

eg

P = ['*.txt','*.py']

I expected I would somehow be able to use list comprehensions to do
this, but in the end I could only do this hackish thing

import operator, glob
F = reduce(operator.add,[glob.glob(p) for p in P],[])


is there a more pythonic approach?
 
D

Duncan Booth

I want to use a list of glob patterns to create a single flat list of
files

eg

P = ['*.txt','*.py']

I expected I would somehow be able to use list comprehensions to do
this, but in the end I could only do this hackish thing

import operator, glob
F = reduce(operator.add,[glob.glob(p) for p in P],[])


is there a more pythonic approach?

If you want a list comprehension then how about:

filenames = [ name for pat in PATTERNS for name in glob.glob(pat) ]
 
P

Peter Otten

Duncan said:
If you want a list comprehension then how about:

filenames = [ name for pat in PATTERNS for name in glob.glob(pat) ]
PATTERNS = ["*t", "*xt"]
filenames = [name for pat in PATTERNS for name in glob.glob(pat)]
len(filenames), len(sets.Set(filenames))
(66, 39)

Names that match more than one pattern will appear more than once in the
list.

Peter
 
P

Peter Otten

Robin said:
I want to use a list of glob patterns to create a single flat list of
files

eg

P = ['*.txt','*.py']

I expected I would somehow be able to use list comprehensions to do
this, but in the end I could only do this hackish thing

import operator, glob
F = reduce(operator.add,[glob.glob(p) for p in P],[])


is there a more pythonic approach?

Here's how I would do it in 2.4:

patterns = ["*.txt", "*.py"]

def matchAny(name, patterns):
return True in (fnmatch.fnmatch(name, p) for p in patterns)

matches = [fn for fn in os.listdir(".") if matchAny(fn, patterns)]

Note that the result is slightly different: files starting with a dot are
not filtered out.

Peter
 
D

Duncan Booth

Duncan said:
If you want a list comprehension then how about:

filenames = [ name for pat in PATTERNS for name in glob.glob(pat) ]
PATTERNS = ["*t", "*xt"]
filenames = [name for pat in PATTERNS for name in glob.glob(pat)]
len(filenames), len(sets.Set(filenames))
(66, 39)

Names that match more than one pattern will appear more than once in the
list.
As indeed they do in the original posting. I assumed that either Robin
wanted that behaviour or knew it wasn't relevant (the example given had
non-overlapping patterns).

To remove duplicates just pass through a dictionary or a set:

filenames = dict.fromkeys(filenames).keys()
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,744
Messages
2,569,482
Members
44,901
Latest member
Noble71S45

Latest Threads

Top