I have a list of lists, and I want to make a function that checks if each of the lists inside have exactly one item in common with all the other lists, if so return True.
Couldn't make it work, is there a simple way to do it without using modules?
I've tried something like this:
list_of_lists = [['d','b','s'],['e','b','f'],['s','f','l'],['b','l','t']]
new_list = []
for i in list_of_lists:
for item in i:
new_list.append(item)
if len(set(new_list)) == len(new_list)-len(list_of_lists):
return True
if you want to intersect all the items in the sublist you can convert them to a set and find intersection check if its an empty set.
list_of_lists = [['d','b','s'],['e','b','f'],['s','f','l'],['b','l','t']]
common_items = set.intersection(*[set(_) for _ in list_of_lists])
if len(common_items) == 1:
return True
return False
Using list comprehension:
def func(list_of_lists):
return sum([all([item in lst for lst in list_of_lists[1:]]) for item in list_of_lists[0]]) == 1
Works if each is guaranteed for one of each item. Also if its not, returns True only if there is one match.
use the Counter after joining a list and a compare list to determine occurrences. Ensure at least one item in the resulting list has a frequency of 2.
from collections import Counter
list_of_lists = [['d','b','s'],['e','b','f'],['s','f','l'],['b','l','t']]
for i in range(len(list_of_lists)):
for j in range(i+1,len(list_of_lists)):
result=(list_of_lists[i]+list_of_lists[j])
counts=(Counter(result))
matches={x for k,x in counts.items() if x==2}
if len(matches)==0:
print("missing a match")
Related
I was trying to return the True value when writing the statement:
list = [[],[],[],[]]
list == []
Instead it returns False
My nested list consists of a variable number of empty lists.
How do I write a single statement that could apply to nested list of [1/2/3...] empty lists?
all(x == [] for x in your_list)
to return True if all empty
any(x != [] for x in your_list)
to return True if at least on is not empty
You could first remove all empty lists and then check if the result equals an empty list, you could do this in a single line as follows:
[x for x in list if x != []] == []
You can make use of all in python to match a condition for all elements in a list. In this case the condition is if the element is an empty list or not.
>>> my_list = [[], [], []]
>>> all([x == [] for x in my_list])
True
If you are sure that all items in your list are lists you can use any directly because the truthy value of [] is False
list_of_lists = [[],[],[],[]]
if not any(list_of_lists):
# all lists are empty (or list_of_lists itself is empty)
Various uses of any and all will allow you to check other similar conditions:
if any(list_of_list):
# at least one of the list is not empty
if all(list_of_list):
# none of the lists are empty
if not all(list_of_list):
# at least one of the lists is empty
I do not completely understand your problem but if you want to detect an empty list or a nested list of empty list try by getting keeping only unique elements (say your list is l)
if l ==[] or list(set(l))==[[]]:
Use any() function.
list = [[], [], []]
any(list) == bool([]) # evaluates to True
In python, bool value of an empty list is False and any function returns False if none of the values inside the list are True.
I have list
players = [[['QB1',7000,20],['RB1',4500,12],['RB2',3800,11]],
[['QB1',7000,20],['RB2',3800,11],['RB1',4500,12]]]
How do I get the first element of each inner-most lists ('QB1', 'RB1' and 'RB2' from the first "secondary," if you will, list) to check if they are the same, however disordered labels as those in another secondary list (they are in this case as both secondary lists contain 'QB1', 'RB1' and 'RB2')?
EDIT:
My desired out is [['QB1','RB1','RB2'],['QB1','RB2','RB1']]. I want to have some way of identifying that these are, for my purpose, the same list.
You can do this:
output = [[i[0] for i in a] for a in players]
The output will be like this:
[['QB1', 'RB1', 'RB2'], ['QB1', 'RB2', 'RB1']]
you can use recursive search for that and get first element of each list or whole list
players = [[['QB1',7000,20],['RB1',4500,12],['RB2',3800,11]],[['QB1',7000,20],['RB2',3800,11],['RB1',4500,12]]]
def retrive_first(lst):
for item in lst:
if type(item) == list:
retrive_first(item)
else:
print "returning ---> ", lst[0]
return lst[0]
print retrive_first(players)
You could also try this:
from operator import itemgetter
[list(map(itemgetter(0), player)) for player in players]
do:
print(list(zip(players))[0])
Or:
print([i[0] for i in players])
I have two lists and want a count of how many times elements in a list are an exact match and are in the same position as another list. So for example:
list1 = [1,2,3,4]
list2 = [1,2,4,3]
would return 2.
I have the following code:
count = 0
def corrpos(list1, list2, count):
if list1[0] == list2[0]:
count = 1
return count
this works to compare the first element, but I am unsure how to make it keep track for all the elements. Any tips?
You can make a list comprehension and calculate the number of elements of list1 that were present in list2 by using len():
print len([x for x in list1 if x in list2])
Your own code is also working, you would just have to return count (and change the input of the parameter correctly to list2):
return count
For the sake of completeness I will propose an answer using the built-in zip, so the last answer provided by #LMc could be rewritten as :
def corrpos(list1, list2):
count = 0
for elem1, elem2 in zip(list1, list2):
if elem1 == elem2:
count += 1
return count
It didn't really provide something more, but zip allow you to iterate "in the same time" on two iterables and I guess this method is more intuitive than having to use the index of the elements from the first list to select those from the second list as in the example with enumerate.
Of course it can also be rewritten to be a oneliner as in the other answers :
def corrpos(list1, list2):
return sum(1 for elem1, elem2 in zip(list1, list2) if elem1 == elem2)
or
def corrpos(list1, list2):
return len([True for elem1, elem2 in zip(list1, list2) if elem1 == elem2])
Another way you could do this is see the intersection of these two lists using sets:
>>>set(list1) & set(list2)
set([1, 2, 3, 4])
Then you can just use the len function to get a count:
>>>len(set(list1) & set(list2))
4
Update:
Given that the elements have to be in the same index location, I would use a list comprehension:
def corrpos(list1,list2):
return len([i for (c,i) in enumerate(list1) if list2[c]==i])
Here the enumerate function keeps track of the index location as you loop through list1 and can be used to look up the corresponding value in list2.
If you want to use a for loop, this can be rewritten as:
def corrpos(list1,list2):
count=0
for (c,i) in enumerate(list1):
if list2[c]==i: count+=1
return count
I have a manifold of lists containing integers. I store them in a list (a list of lists) that I call biglist.
Then I have a second list, eg [1, 2].
Now I want to find all lists out of the big_list that start with the same items as the small list. The lists I want to find must have at least all the items from the second list.
I was thinking this could be done recursively, and came up with this working example:
def find_lists_starting_with(start, biglist, depth=0):
if not biglist: # biglist is empty
return biglist
try:
new_big_list = []
# try:
for smallist in biglist:
if smallist[depth] == start[depth]:
if not len(start) > len(smallist):
new_big_list.append(smallist)
new_big_list = find_lists_starting_with(start,
new_big_list,
depth=depth+1)
return new_big_list
except IndexError:
return biglist
biglist = [[1,2,3], [2,3,4], [1,3,5], [1, 2], [1]]
start = [1, 2]
print(find_lists_starting_with(start, biglist))
However I am not very satisfied with the code example.
Do you have suggestions as how to improve:
- understandability of the code
- efficiency
You can try it via an iterator, like so:
[x for x in big_list if x[:len(start_list)] == start_list]
Here's how I would write it:
def find_lists_starting_with(start, biglist):
for small_list in biglist:
if start == small_list[:len(start)]:
yield small_list
This returns a generator instead, but you can call list to its result to get a list.
For either of the two solutions (#mortezaipo, #francisco-couzo) proposed so far, space efficiency could be improved via a custom startswith method to avoid constructing a new list in small_list[:len(start_list)]. For example:
def startswith(lst, start):
for i in range(len(start)):
if start[i] != lst[i]:
return False
return True
and then
[lst for lst in big_list if startswith(lst, start_list)]
(modeled after #mortezaipo's solution).
python3 program that takes input a list and output if it is unique or not. The following is an example:
list_a = [1,2,3,4,5] #unique
list_b = [1,2,2,3,4] #not unique
I have wrote a python3 script for this problem:
for i in range(len(list_a)):
j = i+1
for j in range(len(list_a)):
if list_a[i] == list_a[j]:
print ("not unique")
else:
print ("unique")
Is this the only way to check it. I bet it isn't! I want some optimized code that is equivalent to above or simply that ouputs "unique" or "not unique" for a given list.
Thank you in advance.
The easiest way to do this is compare length of set of given list with length of list:
if len(l) != len(set(l)):
# not unique
You can use all() and sets, this will short-circuit as soon as a repeated item is found.
>>> def solve(lis):
... seen = set()
... return all(item not in seen and not seen.add(item) for item in lis)
...
>>> solve(range(5))
True
>>> solve([1,2,2,3,4])
False
Throw the list into a set:
set_a = set(list_a)
if len(set_a) == len(list_a):
print("unique")
else:
print("not unique")
You could use AVL Trees, add each element one by one in the tree while the inserted element is not yet in the tree.
In the case of big lists, it will be very fast in comparison of your current code.
If you want to easily find duplicate elements you can use collections.Counter:
import collections
a = [1, 2, 2, 3]
b = collections.Counter(a)
duplicates = [i for i in b if b[i] > 1]
Variable b is an object which acts a bit like a dictionary with keys being values from a and values being numbers indicating how many times this value appeared in the original list.
print(b[2])
would give 2.
Variable duplicates has all duplicate elements and you can use it like this:
if duplicates:
print("not unique")
else:
print("unique")
This is longer than generating a set, but you have much more information you can use.