Combine unknown amount of lists, keep only common values - python

I want to combine N lists and keep only the values that are in every single one of them. I don't know how many lists there are, so the code must be dynamic.
a_list = [(3, -1), (3, -1), (3, 0), (4, -1), (3, 1), (5, -1), (3, 2), (6, -1), (3, 3), (7, -1), (7, -1), (3, 3), (7, 0), (4, 3), (7, 1), (5, 3), (7, 2), (6, 3), (7, 3), (7, 3)]
b_list = [(-3, 3), (-3, 3), (-3, 4), (-2, 3), (-3, 5), (-1, 3), (-3, 6), (0, 3), (-3, 7), (1, 3), (-3, 8), (2, 3), (-3, 9), (3, 3), (3, 3), (-3, 9), (3, 4), (-2, 9), (3, 5), (-1, 9), (3, 6), (0, 9), (3, 7), (1, 9), (3, 8), (2, 9), (3, 9), (3, 9)]
a = set(a_list)
b = set(b_list)
print(list(a&b))
This code works perfectly for a known number of lists, but I don't know how many lists there are.
Note: "Unknown number of lists" means it depends on the values the script is ran with.
Edit: N > 0

You can use the built-in set function intersection:
print (set.intersection(*map(set, lists)))

Use reduce
import functools
list_of_sets = [set(x) for x in list_of_lists]
intersection = functools.reduce(lambda x, y: x & y, list_of_sets)

Related

How to select spesific list from nested lists with python [duplicate]

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)]]

Compare pairs of values within a list

I have a list:
points = [(4, 5), (-0, 2), (4, 7), (1, -3), (3, -2), (4, 5),
(3, 2), (5, 7), (-5, 7), (2, 2), (-4, 5), (0, -2),
(-4, 7), (-1, 3), (-3, 2), (-4, -5), (-3, 2),
(5, 7), (5, 7), (2, 2), (9, 9), (-8, -9)]
equal_values = 0
I'd like to count how many times in this list each pair of values are equal e.g. (2, 2). How can I define that condition in an if statement?
if ??? in points:
equal_values +=1
You can do it quickly by this:
len([i for i in points if i[0]==i[1]])
Or with a common for loop combined with if statement, like below:
equal_values = 0
for i in points:
if i[0]==i[1]:
equal_points+=1
The output is 3 for both ways, for your given list
You want this ?
points = [(4, 5), (-0, 2), (4, 7), (1, -3), (3, -2), (4, 5),
(3, 2), (5, 7), (-5, 7), (2, 2), (-4, 5), (0, -2),
(-4, 7), (-1, 3), (-3, 2), (-4, -5), (-3, 2),
(5, 7), (5, 7), (2, 2), (9, 9), (-8, -9)]
print(points.count((2, 2)))
To count the number of the (2, 2) occurence in your list ?
this should work:
equal = [i for i in points if i[0] == i[1]]
then get the count (length of the list):
len(equal)
how does that work?
it loops through the elements in points and checks if the 0th and the 1st index's are equal
it appends that item to a list if it is equal
we get the count of equal pairs by checking the length of the list
Try this:
for x in points:
m = list(iterable(x))
if len(set(m)) == 1:
equal_values += 1

Checking if the numbers in a list in a list are in a certain range

So I have a list with multiple list in it which represent something like coordinates. In my case they are positions on a chessboard.
The list would look something like this:
[(3, 3), (4, 3), (5, 3), (6, 3), (3, 4), (4, 4), (5, 4), (6, 4), (3, 5), (4, 5)]
This is just an example.
My problem is, I need to check if any of these coordiantes are out of a certain range, on the chessboard, for example 1-8. Unfortunately i could only get the all() command to work with a list which just consists of numbers and not a list with lists of numbers.
Then iterate through each of the individual coordinates:
>>> coords = [(3, 3), (4, 3), (5, 3), (6, 3), (3, 4), (4, 4), (5, 4), (6, 4), (3, 5), (4, 5)]
>>> all(1 <= c <= 8 for coord in coords for c in coord)
True
Let's try two cases where there is a coordinate out of range:
>>> coords = [(3, 3), (4, 3), (5, 3), (6, 3), (3, 4), (0, 5), (4, 4), (5, 4), (6, 4), (3, 5), (4, 5)]
>>> all(1 <= c <= 8 for coord in coords for c in coord)
False
>>> coords = [(3, 3), (4, 3), (5, 3), (6, 3), (4, 88), (3, 4), (4, 4), (5, 4), (6, 4), (3, 5), (4, 5)]
>>> all(1 <= c <= 8 for coord in coords for c in coord)
False
you can import numpy module and use function max
import numpy as np
>>> l =np.array([(3, 3), (4, 3), (5, 3), (6, 3), (3, 4), (4, 4), (5, 4), (6, 4), (3, 5), (4, 5)])
>>> l.max()
6

find combinations in arbitrarily nested lists under conditions

I want to find possible paths on a finite grid of points. Say, starting point is (x,y). Then next point (m,n) in the path is given by conditions
(m!=x) and (n!=y) ie. I exclude the row and column I was in previously.
n < y ie. I always hop DOWN.
m,n >= 0 ie. all the points are always in first quadrant
Stopping criteria is when a point lies on x axis.
Hence, generate all possible combinations of such 'paths' possible.
Following is what I've tried.
def lisy(x,y):
return [(i,j) for i in range(4,0,-1) for j in range(4,0,-1) if(i!=x and j<y)]
def recurse(x,y):
if (not lisy(x,y)):
return (x,y)
else:
return [(x,y), [recurse(i,j) for i,j in lisy(x,y)]]
OUTPUT:
In [89]: recurse(1,4)
Out[89]:
[(1, 4),
[[(4, 3),
[[(3, 2), [(4, 1), (2, 1), (1, 1)]],
(3, 1),
[(2, 2), [(4, 1), (3, 1), (1, 1)]],
(2, 1),
[(1, 2), [(4, 1), (3, 1), (2, 1)]],
(1, 1)]],
[(4, 2), [(3, 1), (2, 1), (1, 1)]],
(4, 1),
[(3, 3),
[[(4, 2), [(3, 1), (2, 1), (1, 1)]],
(4, 1),
[(2, 2), [(4, 1), (3, 1), (1, 1)]],
(2, 1),
[(1, 2), [(4, 1), (3, 1), (2, 1)]],
(1, 1)]],
[(3, 2), [(4, 1), (2, 1), (1, 1)]],
(3, 1),
[(2, 3),
[[(4, 2), [(3, 1), (2, 1), (1, 1)]],
(4, 1),
[(3, 2), [(4, 1), (2, 1), (1, 1)]],
(3, 1),
[(1, 2), [(4, 1), (3, 1), (2, 1)]],
(1, 1)]],
[(2, 2), [(4, 1), (3, 1), (1, 1)]],
(2, 1)]]
This gives me a nested lists of possible new points from each point.
Can anyone tell me how to process my list obtained from recurse(1,4)?
edit1:
Effectively I hop from a given starting point (in a 4x4 grid [finite]), satisfying the three conditions mentioned until stopping criteria is met, ie. m,n > 0
I clarify the requirements I am working under in the docstring of my generator gridpaths(). Note that I have the horizontal size of the grid as a global variable and the vertical size of the grid is irrelevant, the x-coordinates of path points can be up to but not exceed that global value, and x-coordinates of non-consecutive path points can be equal (though consecutive path points must have different x-coordinates). I changed the name of the routine but kept the arguments as you had them. This version of my code adds the requirement that the y-coordinate of the final point on the path must be 1, and it also is safer in accepting arguments.
This is a generator of lists, so my test code shows how large the generator is then prints all the lists.
def gridpaths(x, y):
"""Generate all paths starting at (x,y) [x and y must be positive
integers] where, if (m,n) is the next point in the path after
(x,y), then m and n are positive integers, m <= xsize [xsize is a
global variable], m != x, and n < y, and so on for all consecutive
path points. The final point in the path must have a y-coordinate
of 1. Paths are yielded in lexicographic order."""
def allgridpaths(x, y, pathsofar):
"""Generate all such paths continuing from pathssofar without
the y == 1 requirement for the final path point."""
newpath = pathsofar + [(x, y)]
yield newpath
for m in range(1, xsize+1):
if m != x:
for n in range(1, y):
for path in allgridpaths(m, n, newpath):
yield path
x, y = max(int(x), 1), max(int(y), 1) # force positive integers
for path in allgridpaths(x, y, []):
# Only yield paths that end at y == 1
if path[-1][1] == 1:
yield path
# global variable: horizontal size of grid
xsize = 4
print(sum(1 for p in gridpaths(1, 4)), 'paths total.')
for p in gridpaths(1, 4):
print(p)
The printout shows that the point (1,4) in a 4x4 grid yields 48 paths. In fact, gridpaths(x, y) will return (xsize - 1) * xsize ** (y - 2) paths, which can grow very quickly. That is why I programmed a generator of lists rather than a list of lists. Let me know if your requirements are different from what I suppose. The printout from that code above is:
48 paths total.
[(1, 4), (2, 1)]
[(1, 4), (2, 2), (1, 1)]
[(1, 4), (2, 2), (3, 1)]
[(1, 4), (2, 2), (4, 1)]
[(1, 4), (2, 3), (1, 1)]
[(1, 4), (2, 3), (1, 2), (2, 1)]
[(1, 4), (2, 3), (1, 2), (3, 1)]
[(1, 4), (2, 3), (1, 2), (4, 1)]
[(1, 4), (2, 3), (3, 1)]
[(1, 4), (2, 3), (3, 2), (1, 1)]
[(1, 4), (2, 3), (3, 2), (2, 1)]
[(1, 4), (2, 3), (3, 2), (4, 1)]
[(1, 4), (2, 3), (4, 1)]
[(1, 4), (2, 3), (4, 2), (1, 1)]
[(1, 4), (2, 3), (4, 2), (2, 1)]
[(1, 4), (2, 3), (4, 2), (3, 1)]
[(1, 4), (3, 1)]
[(1, 4), (3, 2), (1, 1)]
[(1, 4), (3, 2), (2, 1)]
[(1, 4), (3, 2), (4, 1)]
[(1, 4), (3, 3), (1, 1)]
[(1, 4), (3, 3), (1, 2), (2, 1)]
[(1, 4), (3, 3), (1, 2), (3, 1)]
[(1, 4), (3, 3), (1, 2), (4, 1)]
[(1, 4), (3, 3), (2, 1)]
[(1, 4), (3, 3), (2, 2), (1, 1)]
[(1, 4), (3, 3), (2, 2), (3, 1)]
[(1, 4), (3, 3), (2, 2), (4, 1)]
[(1, 4), (3, 3), (4, 1)]
[(1, 4), (3, 3), (4, 2), (1, 1)]
[(1, 4), (3, 3), (4, 2), (2, 1)]
[(1, 4), (3, 3), (4, 2), (3, 1)]
[(1, 4), (4, 1)]
[(1, 4), (4, 2), (1, 1)]
[(1, 4), (4, 2), (2, 1)]
[(1, 4), (4, 2), (3, 1)]
[(1, 4), (4, 3), (1, 1)]
[(1, 4), (4, 3), (1, 2), (2, 1)]
[(1, 4), (4, 3), (1, 2), (3, 1)]
[(1, 4), (4, 3), (1, 2), (4, 1)]
[(1, 4), (4, 3), (2, 1)]
[(1, 4), (4, 3), (2, 2), (1, 1)]
[(1, 4), (4, 3), (2, 2), (3, 1)]
[(1, 4), (4, 3), (2, 2), (4, 1)]
[(1, 4), (4, 3), (3, 1)]
[(1, 4), (4, 3), (3, 2), (1, 1)]
[(1, 4), (4, 3), (3, 2), (2, 1)]
[(1, 4), (4, 3), (3, 2), (4, 1)]

Making Combinations (Python)

In Python, is there a better way to get the set of combinations of n elements from a k-element set than nested for loops or list comprehensions?
For example, say from the set [1,2,3,4,5,6] I want to get [(1,2),(1,3),(1,4),(1,5),(1,6),(2,3),(2,4),(2,5),(2,6),(3,4),(3,5),(3,6),(4,5),(4,6),(5,6)]. Is there a better of of making it than
nums=[1,2,3,4,5,6]
doubles=[]
for a in nums:
for b in nums[a+1:]
doubles.append((a,b))
? It's okay if the elements of the list we end up with are sets, tuples, or lists; I just feel there should be an easier way to do this.
You can use itertools.combinations:
>>> from itertools import combinations
>>> nums = [1,2,3,4,5,6]
>>> list(combinations(nums, 2))
[(1, 2), (1, 3), (1, 4), (1, 5), (1, 6), (2, 3), (2, 4), (2, 5), (2, 6), (3, 4), (3, 5), (3, 6), (4, 5), (4, 6), (5, 6)]
The itertools module has a lot of really powerful tools that can be used in situations like this. In this case, you want itertools.combinations. Some other ones that you might find useful are itertools.combinations_with_replacement and itertools.permutations.
Example:
>>> import itertools
>>> list(itertools.combinations(range(1,7),2))
[(1, 2), (1, 3), (1, 4), (1, 5), (1, 6), (2, 3), (2, 4), (2, 5), (2, 6), (3, 4), (3, 5), (3, 6), (4, 5), (4, 6), (5, 6)]
>>> list(itertools.combinations_with_replacement(range(1,7),2))
[(1, 1), (1, 2), (1, 3), (1, 4), (1, 5), (1, 6), (2, 2), (2, 3), (2, 4), (2, 5), (2, 6), (3, 3), (3, 4), (3, 5), (3, 6), (4, 4), (4, 5), (4, 6), (5, 5), (5, 6), (6, 6)]
>>> list(itertools.permutations(range(1,7),2))
[(1, 2), (1, 3), (1, 4), (1, 5), (1, 6), (2, 1), (2, 3), (2, 4), (2, 5), (2, 6), (3, 1), (3, 2), (3, 4), (3, 5), (3, 6), (4, 1), (4, 2), (4, 3), (4, 5), (4, 6), (5, 1), (5, 2), (5, 3), (5, 4), (5, 6), (6, 1), (6, 2), (6, 3), (6, 4), (6, 5)]
You could use the itertools module
import itertools
alphabet = ['1','2','3','4','5','6']
combos = list(itertools.combinations(alphabet, 2))
print combos

Categories

Resources