Compare unique string values between two lists and get the count of matched values in python - python-3.x

I have two lists with some items in common and some not. I would like to compare the two lists and get the count of items that matched.
list1 = ['apple','orange','mango','cherry','banana','kiwi','tomato','avocado']
list2 = ['orange','avocado','kiwi','mango','grape','lemon','tomato']
Pls advice how to do this in python

Use Counters and dictionary comprehension.
list1 = ['apple','orange','mango','cherry','banana','kiwi','tomato','avocado']
list2 = ['orange','avocado','kiwi','mango','grape','lemon','tomato']
c1 = Counter(list1)
c2 = Counter(list2)
matching = {k: c1[k]+c2[k] for k in c1.keys() if k in c2}
print(matching)
print('{} items were in both lists'.format(len(macthing))
Output:
{'avocado': 2, 'orange': 2, 'tomato': 2, 'mango': 2, 'kiwi': 2}
5 items were in both lists

I think you can use set.intersection within a comprehension like this example:
list1 = ['apple','orange','mango','cherry','banana','kiwi','tomato','avocado']
list2 = ['orange','avocado','kiwi','mango','grape','lemon','tomato']
result = {elm: list1.count(elm) + list2.count(elm) for elm in set.intersection(set(list1), set(list2))}
Output:
{'kiwi': 2, 'avocado': 2, 'orange': 2, 'tomato': 2, 'mango': 2}

Related

Python reverse dictionary lookup in list comprehension

I have the following dictionary:
d = {}
d[1] = 'a'
d[2] = 'b'
d[3] = 'c'
d[4] = 'd'
I'd like to perform a reverse dictionary lookup for each character in a string:
input_string = "bad"
I get different results when I do this in a list comprehension as opposed to a nested for loop, and I don't understand why. As I understand, the list comprehension and the nested for loop should yield identical results. The list comprehension yields a list whose results are not in the order I would expect. My desired result here is that which is provided by the nested for loop, however I prefer to use the list comprehension to accomplish that. Perhaps this has something to do with python dictionary order of which I am unaware?
result1 = [key for key, value in d.items() for i in input_string if i == value]
print(result1)
> [1, 2, 4]
result2 = list()
for i in input_string:
for key, value in d.items():
if i == value:
result2.append(key)
print(result2)
> [2, 1, 4]
In order to mimic the traditional loop, the outer loop should be over input_string and the inner loop should be over d in the list comprehension:
out = [k for i in input_string for k,v in d.items() if i==v]
Output:
[2, 1, 4]

List item extraction in Python

If I have list = [1, [a,b]], how can I make split the list item in list to become list = [1, a], [1,b]?
You can first create a list then another.
then run nested for loops to individually print out each component of list2 + each component of list 1.
I spent a lot of time in this, so hope this has helped you out:
list1 = ["a", "b"]
list2 = [1, list1]
for i in list2[:-1]:
for j in list1:
print(str(i) + str(j))
If it helped, I would wish to get an 'accepted' mark!

Python: Convert 2d list to dictionary with indexes as values

I have a 2d list with arbitrary strings like this:
lst = [['a', 'xyz' , 'tps'], ['rtr' , 'xyz']]
I want to create a dictionary out of this:
{'a': 0, 'xyz': 1, 'tps': 2, 'rtr': 3}
How do I do this? This answer answers for 1D list for non-repeated values, but, I have a 2d list and values can repeat. Is there a generic way of doing this?
Maybe you could use two for-loops:
lst = [['a', 'xyz' , 'tps'], ['rtr' , 'xyz']]
d = {}
overall_idx = 0
for sub_lst in lst:
for word in sub_lst:
if word not in d:
d[word] = overall_idx
# Increment overall_idx below if you want to only increment if word is not previously seen
# overall_idx += 1
overall_idx += 1
print(d)
Output:
{'a': 0, 'xyz': 1, 'tps': 2, 'rtr': 3}
You could first convert the list of lists to a list using a 'double' list comprehension.
Next, get rid of all the duplicates using a dictionary comprehension, we could use set for that but would lose the order.
Finally use another dictionary comprehension to get the desired result.
lst = [['a', 'xyz' , 'tps'], ['rtr' , 'xyz']]
# flatten list of lists to a list
flat_list = [item for sublist in lst for item in sublist]
# remove duplicates
ordered_set = {x:0 for x in flat_list}.keys()
# create required output
the_dictionary = {v:i for i, v in enumerate(ordered_set)}
print(the_dictionary)
""" OUTPUT
{'a': 0, 'xyz': 1, 'tps': 2, 'rtr': 3}
"""
also, with collections and itertools:
import itertools
from collections import OrderedDict
lstdict={}
lst = [['a', 'xyz' , 'tps'], ['rtr' , 'xyz']]
lstkeys = list(OrderedDict(zip(itertools.chain(*lst), itertools.repeat(None))))
lstdict = {lstkeys[i]: i for i in range(0, len(lstkeys))}
lstdict
output:
{'a': 0, 'xyz': 1, 'tps': 2, 'rtr': 3}

Make a list with non-decreasing order elements of a list in Python

I have a list a = [2,2,1,3,4,1] .
I want to make a new list c with the non-decreasing elements lists of list a.
That means my expected form is -
c = [[2,2],[1,3,4],[1]]
Here is my code:
>>> c = []
>>> for x in a:
... xx = a[0]
... if xx > x:
... b = a[:x]
... c.append(b)
... a = a[x:]
but my output is:
>>> c
[[2], [2]]
How can i make a list with all non-decreasing part of list a?
You can initialise the first entry of c with [a[0]] and then either append the current value from a to the end of the current list in c if it is >= the previous value, otherwise append a new list containing that value to c:
a = [2,2,1,3,4,1]
c = [[a[0]]]
last = a[0]
for x in a[1:]:
if x >= last:
c[-1].append(x)
else:
c.append([x])
last = x
print(c)
Output:
[[2, 2], [1, 3, 4], [1]]
If I understand what you are after correctly then what you want is to split the list every time the number decreases. If so then this should do what you need
c = []
previous_element = a[0]
sub_list = [previous_element]
for element in a[1:]:
if previous_element > element:
c.append(sub_list)
sub_list = []
previous_element = element
sub_list.append(previous_element)
c.append(sub_list)
Output:
In [1]: c
Out[2]: [[2, 2], [1, 3, 4], [1]]
There is possibly a clearer way to right the above, but it's pre coffee for me ;)
Also note that this code assumes that a will contain at least one item, if that is not always the case then you will need to either add an if statement around this, or re-structure the loop in a more while loop

return dictionary of file names as keys and word lists with words unique to file as values

I am trying to write a function to extract only words unique to each key and list them in a dictionary output like {"key1": "unique words", "key2": "unique words", ... }. I start out with a dictionary. To test with I created a simple dictionary:
d = {1:["one", "two", "three"], 2:["two", "four",
"five"], 3:["one","four", "six"]}
My output should be:
{1:"three",
2:"five",
3:"six"}
I am thinking maybe split in to separate lists
def return_unique(dct):
Klist = list(dct.keys())
Vlist = list(dct.values())
aList = []
for i in range(len(Vlist)):
for j in Vlist[i]:
if
What I'm stuck on is how do I tell Python to do this: if Vlist[i][j] is not in the rest of Vlist then aList.append(Vlist[i][j]).
Thank you.
You can try something like this:
def return_unique(data):
all_values = []
for i in data.values(): # Get all values
all_values = all_values + i
unique_values = set([x for x in all_values if all_values.count(x) == 1]) # Values which are not duplicated
for key, value in data.items(): # For Python 3.x ( For Python 2.x -> data.iteritems())
for item in value: # Comparing values of two lists
for item1 in unique_values:
if item == item1:
data[key] = item
return data
d = {1:["one", "two", "three"], 2:["two", "four", "five"], 3:["one","four", "six"]}
print (return_unique(d))
result >> {1: 'three', 2: 'five', 3: 'six'}
Since a key may have more than one unique word associated with it, it makes sense for the values in the new dictionary to be a container type object to hold the unique words.
The set difference operator returns the difference between 2 sets:
>>> a = set([1, 2, 3])
>>> b = set([2, 4, 6])
>>> a - b
{1, 3}
We can use this to get the values unique to each key. Packaging these into a simple function yields:
def unique_words_dict(data):
res = {}
values = []
for k in data:
for g in data:
if g != k:
values += data[g]
res[k] = set(data[k]) - set(values)
values = []
return res
>>> d = {1:["one", "two", "three"],
2:["two", "four", "five"],
3:["one","four", "six"]}
>>> unique_words_dict(d)
{1: {'three'}, 2: {'five'}, 3: {'six'}}
If you only had to do this once, then you might be interested in the less efficeint but more consice dictionary comprehension:
>>> from functools import reduce
>>> {k: set(d[k]) - set(reduce(lambda a, b: a+b, [d[g] for g in d if g!=k], [])) for k in d}
{1: {'three'}, 2: {'five'}, 3: {'six'}}

Resources