This question already has answers here:
What do lambda function closures capture?
(7 answers)
Closed 8 years ago.
I am trying to familiarize with itertools. As an exercise, I am trying to generate (x,y) integer pairs satisfying -1 < y < x <5. The following code using itertools produces incorrect results:
from itertools import *
xs = xrange(0,5)
allPairs = chain(*(izip(repeat(x), takewhile(lambda y: y < x, count())) for x in xs))
print list(allPairs)
The output is
[(0, 0), (0, 1), (0, 2), (0, 3), (1, 0), (1, 1), (1, 2), (1, 3), (2, 0), (2, 1), (2, 2), (2, 3), (3, 0), (3, 1), (3, 2), (3, 3), (4, 0), (4, 1), (4, 2), (4, 3)]
The problem seems to be that the lambda function within the takewhile is using x = 4, the maximum in the range.
If I modify the code above to explicitly construct a lambda function for each x as follows the output is computed correctly.
from itertools import *
xs = xrange(0,5)
xypair = lambda x: izip(repeat(x), takewhile(lambda y: y < x, count()))
allPairs = chain(*(xypair(x) for x in xs))
print list(allPairs)
Output:
[(1, 0), (2, 0), (2, 1), (3, 0), (3, 1), (3, 2), (4, 0), (4, 1), (4, 2), (4, 3)]
Any idea why in the first code the lambda is constructed only using the last value of the iteration over xs?
Try something a bit simpler:
combinations(iterable,r): r-length tuples, in sorted order, no repeated elements
>>> list(combinations(xrange(0,5),2))
[(0, 1), (0, 2), (0, 3), (0, 4), (1, 2), (1, 3), (1, 4), (2, 3), (2, 4), (3, 4)]
Related
I am trying to do a list comprehension of a tuples list based on another list of tuples with partial match.
x = [((1,1),(1,1),(1,2)),
((2,1),(1,3),(2,9)),
((2,1),(2,3),(2,9))]
y = [(2,1),(1,3)]
[i for i in x for k in y if k in i]
e.g. in this x is a list of tuples & y is the desired list of tuples. If y is found in any of the items in the list of tuples in x, it should return that item.
Result is: [((2, 1), (1, 3), (2, 9)), ((2, 1), (1, 3), (2, 9)), ((2, 1), (2, 3), (2, 9))]
But I want only : [((2, 1), (1, 3), (2, 9))]
I tried with single tuple & it gave the desired result. But not sure why it doesn't work when I pass a tuple list.
x = [((1,1),(1,1),(1,2)),
((2,1),(1,3),(2,9)),
((2,1),(2,3),(2,9))]
y = (2,1)
[i for i in x if y in i]
Result: [((2, 1), (1, 3), (2, 9)), ((2, 1), (2, 3), (2, 9))]
If it doesn't have to be a comprehension:
[*filter({*y}.issubset, x)]
all is the ticket here, determining if all tuples in y are in each element in x.
[
tpl
for tpl in x
if all(tpl2 in tpl
for tpl2 in y)
]
# [((2, 1), (1, 3), (2, 9))]
You can use:
x = [
((1, 1), (1, 1), (1, 2)),
((2, 1), (1, 3), (2, 9)),
((2, 1), (2, 3), (2, 9)),
]
y = [(2, 1), (1, 3)]
print([t for t in x if not set(y).difference(t)])
output:
[((2, 1), (1, 3), (2, 9))]
If you subtract tuples inside x from y with set operations, if all the sub tuples are present, you'll end up with an empty set, so you want that tuple.
You could also write if set(y).issubset(t) instead of if not set(y).difference(t) part.(borrowed from #kellyBundy's answer)
What if I want any tpl of y to be true but not all.
print([t for t in x if set(y).intersection(t)])
This question already has answers here:
Pythonic way of checking if a condition holds for any element of a list
(3 answers)
Apply function to each element of a list
(4 answers)
Closed 9 months ago.
Hello guys I have list like A
max_x=4
min_x=0
A=[[(0, 1), (1, 0), (1, 1), (2, 0)], [(0, 3), (1, 3), (1, 4), (2, 2), (2, 3), (2, 4), (3, 1), (3, 2), (3, 3), (3, 4), (4, 0), (4, 1), (4, 2)]]
A, includes different group of points (x,y) format.I wanted to find group if includes my max and min same time.Output should be like B.Because this cluster includes 0 and 4 as x.
B= [(0, 3), (1, 3), (1, 4), (2, 2), (2, 3), (2, 4), (3, 1), (3, 2), (3, 3), (3, 4), (4, 0), (4, 1), (4, 2)]
Thank you.
You could use a list comprehension to find any sublists of A that have a tuple that has x == min_x and also a tuple that has x == max_x:
max_x=4
min_x=0
A=[[(0, 1), (1, 0), (1, 1), (2, 0)], [(0, 3), (1, 3), (1, 4), (2, 2), (2, 3), (2, 4), (3, 1), (3, 2), (3, 3), (3, 4), (4, 0), (4, 1), (4, 2)]]
B = [l for l in A if any(x == min_x for x,_ in l) and any(x == max_x for x,_ in l)]
Output:
[[(0, 3), (1, 3), (1, 4), (2, 2), (2, 3), (2, 4), (3, 1), (3, 2), (3, 3), (3, 4), (4, 0), (4, 1), (4, 2)]]
Here's a snippet with a regular itertools.product usage:
from itertools import product
arr = [1,2,3]
pairs = list(product(arr, arr))
# pairs = [(1, 1), (1, 2), (1, 3), (2, 1), (2, 2), (2, 3), (3, 1), (3, 2), (3, 3)]
Now I would like to have these points yielded in an order which can be achieved by sorting the resulting tuples in the following way:
sorted(pairs, key=lambda y:max(y))
# [(1, 1), (1, 2), (2, 1), (2, 2), (1, 3), (2, 3), (3, 1), (3, 2), (3, 3)]
Is there a way for me to input those numbers to itertools.product so it yields the tuples in this order, or do I need to sort the pairs after iterating over the results of itertools.product?
You can probably use your own modified approach to achieve this in one go.
sorted([(x, y) for x in [1, 2, 3] for y in [1, 2, 3]], key=lambda y:max(y))
OUTPUT
[(1, 1), (1, 2), (2, 1), (2, 2), (1, 3), (2, 3), (3, 1), (3, 2), (3, 3)]
How would I implement the following using python? I've tried using lambda expressions and a few other methods, but I'm not getting the desired results. Basically, I should receive a set of relations that satisfy the check. I.E they have to be divisible by each other, so {(1,1), (1,2), (1,3),...(6,6)}.
Here's the actual question:
In Python, set a variable say S = {1,2,3,4,5,6}; then do as follows: "List all the ordered pairs in the relation R = {(a,b) : a divides b} on the set {1,2,3,4,5,6}."
you can do it by list comprehension -
S = [1,2,3,4,5,6]
result = [ (x,y) for x in S for y in S if y%x==0]
You can use itertools.product within a list comprehension,and as you want they be divisible by each other you can use the condition i%j==0 or j%i==0 :
>>> from itertools import product
>>> [(i,j) for i,j in product(S,repeat=2) if i%j==0 or j%i==0]
[(1, 1), (1, 2), (1, 3), (1, 4), (1, 5), (1, 6), (2, 1), (2, 2), (2, 4), (2, 6), (3, 1), (3, 3), (3, 6), (4, 1), (4, 2), (4, 4), (5, 1), (5, 5), (6, 1), (6, 2), (6, 3), (6, 6)]
[{(a,b) : a/b} for a in S for b in S]
For example:
alist=[[(0, 0), (0, 1), (1, 1), (1, 2), (2, 2), (2, 1), (2, 0), (1, 0), (3, 0)],
[(0, 2), (0, 3), (1, 3)],
[(0, 4), (1, 4), (2, 4), (0, 5), (0, 6), (1, 6), (2, 6), (3, 6)],
[(1, 5)],
[(2, 3), (3, 3), (3, 4), (3, 5), (2, 5), (3, 2), (3, 1)]]
for i in dlist:
print(len(i))
print(max(len(i))) #this gives me error
output:
5
9
3
8
1
7
I wanted to print out 9 as my output from the above list. How am I able to print the result?
Somewhat more terse
len(max(alist,key=len))
If you can be sure your nesting is only one level (that is, a list of lists):
print max(len(sublist) for sublist in alist)
functional style using map:
print max(map(len, alist))
If you want the actual index of the longest sublist:
max(((i,l) for i,l in enumerate(alist)), key=lambda t: len(t[1]))[0]
Or, as stated in comments:
max(enumerate(alist), key=lambda t: len(t[1]))[0]