Getting intersection of lists, beginning with the same string - python

I am searching for elements in one list that begin with the elements in the second list
lis = [x for x in LL if any(x.startswith(i) for i in RR)]
This gives me the correct results, however i need to get a list containing the strings from both the LL and RR lists (preferably in a tuple).
(if this sounds odd, because one might think that they would look the same, in this case they do not)
This only gives me the results from list LL
Any suggestions on how to get the results from LL accompanied by the match that was found in RR ?

Try this out
from itertools import product
lis = [(x, y) for x, y in product(LL, RR) if x.startswith(y)]

You can do this:
lis = [(x,i) for x in LL for i in RR if (x.startswith(i))]

Related

How to iterate a zip list and print each index of it after joining to lists of the same size?

Given the variables:
X = ['a', 'b', 'c']
Y = [1, 2, 3]
complete the following statement:
[print(pair) for pair in ...]
so as to print to the screen pairs of elements from X and Y which occupy the same position in the index.
I know I can make a join X and Y and make a list using list(zip(X,Y)) but the adding that in the statement gives an empty list.
I can't solve this problem using the form required any help?
thanks!
Not really clear what you're trying to achieve. If you need to print pairs, zip works, i.e.
for pair in zip(X, Y):
print(pair)
[print(pair) for pair in ...] is list comprehension, this is made to create lists, not to print data:
pairs_list = [pair for pair in zip(X, Y)] # don't do this
which is simply pairs_list = list(zip(X, Y)). Does this make sense to you?
Using list comprehensions to leverage a sideeffect (like printing something) is frowned upon. If you dont need a list, don't build one.
[print(pair) for pair in zip(X,Y)] # no need to list(zip(...))
will result in lots on None ... because the return value of print() is None.
Use a simple loop:
for p in zip(X,Y):
print(p)

Python 3: How to check if the item from list is in list and print it

I have a list of lists, which contains coordinates
points = [[5821, 293], [3214, 872], [4218, 820], [1223, 90], [7438, 820]]
and I need to find pair of lists with the same point[i][1] and then print both of them. This coordinates are given just for instance. In the code they're given randomly.
How to do this?
You can use itertools.combinations to create a series of pairs between each two items, and filter out only those with the same second item:
from itertools import combinations
result = [x for x in combinations(points, 2) if x[0][1] == x[1][1]]
There's no easy and efficient way to do what you want with your current data structure.
You can either use an inefficient method (O(N**2)), or convert your data to another format where you can use a more efficient algorithm.
Mureinik's answer is a good way to do an O(N**2) search, so I'll offer a solution that uses a dictionary to make the checking fast:
def find_matches(points):
dct = {}
for x, y in points:
for other_x in dct.setdefault(y, []):
yield (x, y), (other_x, y)
dct[y].append(x)
This is a generator, which will yield pairs of points with matching y values. It should use O(N) space and O(N+R) time (for N input points and R pairs of matches).
Not sure I understand the question correctly, but here is my approach.
I use python 3.5.2, by the way.
If your intent is to capture all lists with [1] or y-coordinate (depending on how you look at it) with a value of 820, then the code could be:
for i in points:
if i[1] == 820:
print(i)
Here is code that will work for you:
second_list = []
the_list = [[5821, 293], [3214, 872], [4218, 820], [1223, 90],
[7438, 820]]
for i in the_list:
second_list.append(i[1])
repeated = []
the_new_list = sorted(second_list, key=int)
for i in range(len(the_new_list)):
if i + 1 < len(the_new_list):
if the_new_list[i] == the_new_list[i+1]:
repeated.append(the_new_list[i])
for i in the_list:
if i[1] in repeated:
print(i)
second_list stores the y-coordinates of your list. Then, the program sorts the list of y-coordinates in ascending order and appends them to the_new_list. Finally, we loop over the_new_list and see if any numbers after each other are equal, and if so, append them to the list repeated. Then, we loop over the_list and see if any points are in repeated. If so, we print the entire thing. I hope that helps.

Python: What's the "Pythonic" way to process two lists?

Say I have this code in Python. I'm a Perl programmer, as you may be able to tell.
# Both list1 and list2 are a list of strings
for x in list1:
for y in list2:
if y in x:
return True
return False
What's a more Pythonic way to handle this? I assume a list comprehension could do it well, but I can't get my head around the "process two separate lists" part of this.
To convert two nested loops into a nested comprehension, you just do this:
[<expression> for x in list1 for y in list2]
If you've never thought through how list comprehensions work, the tutorial explains it:
A list comprehension consists of brackets containing an expression followed by a for clause, then zero or more for or if clauses. The result will be a new list resulting from evaluating the expression in the context of the for and if clauses which follow it.
In other words, the clauses from left to right in a comprehension match up with statements from top/outside to bottom/inside, and that's all there is to it.
This blog post attempts to put the same idea in yet another way, in case you haven't got it yet.
But here, you don't have an expression, you have a statement.
But you have an expression in there, the y in x part of the statement, and what you want to do is return True if it's every true for any value, which is exactly what any does. So:
return any([y in x for x in list1 for y in list2])
And really, you don't want to build the list here, just iterate over the values, so drop the square brackets to make it a generator expression instead:
return any(y in x for x in list1 for y in list2)
For the simple case of just iterating the cartesian products of multiple iterables, you may want to use itertools.product instead. In this case, I don't think it makes things any simpler or more readable, but if you had four lists instead of two—or an unpredictable-in-advance number of them—that might be a different story:
return any(y in x for x, y in product(list1, list2))
No, a list comprehension can't do it well. You want a boolean result, list comprehensions are for creating lists (and they don't really do early exit). You could use a generator comprehension:
return any(y in x for x, y in itertools.product(list1, list2))
or if you really like using standard libraries for everything (or you think like a functional programmer):
from itertools import starmap, product
from operator import contains
return any(starmap(contains, product(list1, list2))
Steve and abamarts answers are explaining what you asked explicitly, i would try to address what you implied regarding list comprehensions.
A "nested" list comprehension is nothing more then your original nested for loop, but with the twist, that the most inner-block moves up to the top!
for x in list1:
for y in list2:
if y in x:
return True
else:
return False
becomes:
[True if y in x else False for x in list1 for y in list2]
So the for-loops remain more or less in order:
[for x in list1 for y in list2]
then prepend the if-clause:
[if y in x else False for x in list1 for y in list2]
and finally prepend the result for the if-statement to be True:
[True if y in x else False for x in list1 for y in list2]
a nested example:
tpl_list = []
for element in vector:
for x, y in element:
if (x**2+y**2) < 1:
tpl_list.append((1/x, 1/y))
else:
tpl_list.append((x,y))
as a list comprehension (building in steps)
[for e in vector for x,y in e]
[if (x**2+y**2) < 1 else for e in vector for x,y in e]
[(1/x, 1/y) if (x**2+y**2) < 1 else (x,y) for e in vector for x,y in e]

Double list Comprehension with range

I have a list in Python which I'm trying to print the first five elements out of it using list comprehension.
I understand that this has to be done using double list comprehensions. I have the following at the moment:
print [[x[i] for x in mylist] for i in range(0,5)]
This throws the following error: IndexError: tuple index out of range.
When I print each one separately, it works out fine. I do print mylist[0], print mylist[1] etc...
What is the issue here? I have a feeling that my entire double comprehension is not right. Now here's what I'm thinking:
[x for x in range(0,5)]
This creates a list of x's for each x in range(0,5). Since this is my index, I nested another list comprehension statement before that as above to do that over my specific list.
Any help is appreciated. Thanks!
mylist[:5] gives the first 5 elements of mylist. (If mylist has fewer than 5 elements in it, then mylist[:5] will return a list of length len(mylist).) Using a list comprehension here would be overkill.
Provided myList contains at least 5 elements, and you really want to use list comprehension, try this:
[print (mylist[i]) for i in range (0, 5)]
unutbu's is the best solution. Performing it using list comprehensions, you'd want
[mylist[i] for i in range(5)]
As for why you are getting the error, if myList is a list of tuples, look at it like this:
myList = [(0, 1), (1, 2), (2, 3)]
result = []
for i in range(5):
sub_result = []
# Here x will be (0, 1), etc.
for x in myList:
# Here you are referencing the ith element of your tuple
# If your tuple doesn't contain that many elements, you get the error
sub_result.append(x[i])
Therefore it is accessing your tuple and not your list. The other solutions all show how to correct this, so definitely vote for one them - this will hopefully just help figure out why it is causing an error :)
print [mylist[j] for j in [ i for i in range(5)]]
Although #unutbu's approach is much more readable.
You are trying to access indexes that out of range.
It means that your x tuple has length < 5.
It happens for data like [[1,2,3],[4,5,6]..]
x here would be [1,2,3], then [4,5,6] etc
when you try x[5] - you get Exception

excluding lists that have more than one x

I have a bunch of lists that look something like this:
my_list = [x, y, z, x, z, w]
I want to exclude lists that have more than one 'x', however one 'x' is allowed, as well as repeats of other letters.
I'm not quite sure where to start with this...
You can find the number of list items equal to x by
my_list.count(x)
To filter a list of lists for only the lists that contain up to one x, use
[lst for lst in list_of_lists if lst.count(x) <= 1]
Use collections.Counter to count the number of 'x's.
The count() method will return the number of times a certain element appeared in the list, e.g.:
list.count(x)
So you can do something like
if list.count(x) <= 1:

Categories

Resources