I want to do following:
1] compare each element in list a with b and map similar values.
a=[1, 2, 3, 6, 4, 5, 7, 8, 9]
b=[4, 4, 5, 5, 7, 7, 9, 9, 10]
I tried following:
c = set(a) & set(b)
>>> set([9,4,5,7])
2] I want these mapped values in same numbering order as appear in list b, such as 4,5,7,9.
3] and lastly I want to use these key values (4,5,7,9) and generate corresponding values from list a, such as:
4 (1,2)
5 (3,6)
7 (4,5)
9 (7,8)
Any suggestions would be highly appreciative?
Now that you've updated your question, I see that what you really want is just a map of keys to values:
a = [1, 2, 3, 6, 4, 5, 7, 8, 9]
b = [4, 4, 5, 5, 7, 7, 9, 9, 10]
r = dict([(x, []) for x in b])
for k, v in zip(b, a):
r[k] += [v,]
Here's how to use the results:
>>> for k, v in r.items():
... print k, v
...
9 [7, 8]
10 [9,]
4 [1, 2]
5 [3, 6]
7 [4, 5]
>>>
>>> print r[4]
[1, 2]
Here's an optimized version that will work faster with less memory usage:
from itertools import izip
from collections import defaultdict
r = defaultdict(list)
for k, v in izip(b, a):
r[k] += [v]
To solve your problem 3, you will need to compare each list against the opposing set. And that will solve your #2 automatically.
There are other ways to solve #2, like using an OrderedSet (like the recipe linked to in the collections docs), but since they won't solve #3, there's no point getting into that.
If the a values are very large, you might want to build an index structure—a dict that maps values to collections of indices—to make this faster. Like this:
rev_a = collections.defaultdict(list)
for index, value in enumerate(a):
rev_a[value].append(index)
And then the lookup part becomes even easier, and faster:
for b_value in b:
a_indices = rev_a[b_value]
if a_indices:
a_str = ','.join(map(str, a_indices))
print('{} is associated with ({})'.format(b_value, a_str))
Or, if you want to create some kind of structure instead of printing out on the fly:
results = [(b_value, rev_a[b_value]) for b_value in b]
results = OrderedDict((b_value, rev_a[b_value]) for b_value in b)
# etc.
That doesn't actually produce the output you asked for, but… I'm not sure what the output you asked for is supposed to come from. Unless you're taking the matching indices from the other list, then looking them up in the first list? That's… odd to say the least. At any rate, an index structure like this should make it trivial to implement any rule you come up with, even a much odder one, as long as you can explain it.
For example, replace the a_str line with this:
a_str = ','.join(str(a[a_index] for index in a_indices))
… and you get your desired output.
You can use a list comprehension
>>> a=[1, 2, 3, 6, 4, 5, 7, 8, 9]
>>> b=[4, 4, 5, 5, 7, 7, 9, 9, 10]
>>> [x for x in a if x in b]
[4, 5, 7, 9]
Related
For example the list is:
stuff = [1, 2, 5, 7]
Now I created a new list named sum_list to store the summation of each of the 2 elements in stuff. The element in the sum_list will be 1+2, 1+5, 1+7, 2+5, 2+7, 5+7:
[3, 6, 8, 7, 9, 12]
You can do this in one hideous list comprehension:
[a + b for i, a in enumerate(my_list, start=1) for b in my_list[i:]]
Nested loops may be clearer:
result = []
for i, a in enumerate(my_list, start=1):
for b in my_list[i:]:
result.append(a + b)
Use itertools.combinations to get all the combinations of 2 elements, and sum to sum them:
>>> stuff = [1, 2, 5, 7]
>>> from itertools import combinations
>>> [sum(c) for c in combinations(stuff, 2)]
[3, 6, 8, 7, 9, 12]
I have this code where it takes 2 lists as input and prints 3rd list having common elements of both without duplicates.
One approach is the commented for loop which works fine and gives expected result. I am trying to achieve it with list comprehension but it gives duplicates.
a = [1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89]
b = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13]
c=[]
# for i in a:
# if i in b and i not in c:
# c.append(i)
c = [i for i in a if i in b and i not in c ]
print c
Expected result:
[1, 2, 3, 5, 8, 13]
Current result with duplicates using list comprehension:
[1, 1, 2, 3, 5, 8, 13]
I am using python 2.7
A list cannot query itself while it is being built inside a list comprehension. The condition i not in c will always query the same value of c (the empty list []) at the point just before the execution of your list comp, so your code is not aware of what was inserted in the last iteration during the next one.
Option 1
If order does not matter, you could just perform a set intersection:
c = set(a) & set(b)
print(list(c))
[1, 2, 3, 5, 8, 13] # Warning! Order not guaranteed
Option 2
If order matters, use a for loop:
c = []
b = set(b)
for i in a:
if i in b and i not in c:
c.append(i)
print(c)
[1, 2, 3, 5, 8, 13]
Option 3
A slightly faster version of the above which retains order thanks to the use of an OrderedDict:
from collections import OrderedDict
b = set(b)
c = list(OrderedDict.fromkeys([i for i in a if i in b]).keys())
print(c)
[1, 2, 3, 5, 8, 13]
n1 = 20*values[0]
n2 = 100*values[1]
print(n1,"\n",n2)
I've basically got a list above this, with a few values, only if I would have
currently if i have 3 in the first value and 7 in the second, 3 would show up 20 times, and 7 would show up 100 times,
however i would like it to be just multiplied.
Is there any way to do this without importing anything?
--edited again--
I Should have said this much sooner but i didn't realise inputted values would change anything, or factor into anything of this
top of the code i have:
for num in numbers:
values.append(num)
with values being an empty list, and "numbers" is the Input
I think this is what you want
>>> values = [3,7]
>>> n1 = 20 * [values[0]]
>>> n2 = 5 * [values[1]]
>>> print n1
[3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3]
>>> print n2
[7, 7, 7, 7, 7]
number * list_value = product
In [1752]: values = [3, 7]
In [1753]: 20 * values[0]
Out[1753]: 60
When you multiply by an int, the math functions take over. However, in order for repetition, just convert to a str then multiply:
n1 = 20*str(values[0])
n2 = 100*str(values[1])
print(n1,"\n",n2)
If you have a list of values and another list of numbers to multiply the corresponding values with:
values = [12, 14]
multiples = [20, 100]
Then, you can get what you want with:
result = [value * multiple for value, multiple in zip(values, multiples)]
See zip and list comprehensions.
If, on the other hand, you want to repeat the elements in values by the elements in multiples, you can do:
def repeat(values, repeats):
for value, rep in zip(values, repeats):
for _ in range(rep):
yield value
Now, you can use repeat() as a generator to do what you want:
>>> list(repeat([3, 7], [5, 10])
[3, 3, 3, 3, 3, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7]
I'm facing a somewhat troubling problem: I have a list (for example (2, 5, 7, 3, 8)) and I need to remove a couple of those but not all. Let's say I need to remove indexes 1, 3 and 4 and I want to do that in a loop. Is there anyway (in Python or logically) to remove those indexes easily in a loop.
If I have a list remIndexes = (1, 3, 4), as soon as I remove index 1, everything moves down one, so now I have (2, 7, 3, 8) and the indexes for the numbers I wanted to remove are shifted down by one.
Does python provide a neat way of doing this or am I going to have to order the list remIndexes and then go backwards through the list?
Note: remIndexes should be in order, but it could potentially not be in order. Ordering it isn't very hard, however.
UPDATE:
Why does
lst = [1, 2, 3, 4, 5, 6, 7, 8, 9, 0]
for ind, num in enumerate(lst):
print lst.pop(ind)
actually work????? (It prints 2 4 6 8 0 each on a newline.)
Does python freeze a list while you are in a for loop?
Iterate the reversed indexes:
>>> lst = [2, 5, 7, 3, 8]
>>> indexes = 1, 3, 4
>>> for i in reversed(indexes):
... del lst[i]
...
>>> lst
[2, 7]
Or use sorted(indexes, reverse=True) if the indexes is not sorted.
Using list comprehension with enumerate:
>>> lst = [2, 5, 7, 3, 8]
>>> indexes = 1, 3, 4
>>> indexes = set(indexes) # `x in set` is faster than `x in tuple/list`
>>> [x for i, x in enumerate(lst) if i not in indexes]
[2, 7]
This question already has answers here:
Closed 12 years ago.
Possible Duplicate:
In python, how do I take the highest occurrence of something in a list, and sort it that way?
Hi all,
I am looking for an easy way to sort a list by popularity and then remove duplicate elements.
For example, given a list:
[8, 8, 1, 1, 5, 8, 9]
I would then end up with a list like the following:
[8, 1, 5, 9]
>>> lst = [1, 1, 3, 3, 5, 1, 9]
>>> from collections import Counter
>>> c = Counter(lst)
>>> [i for i, j in c.most_common()]
[1, 3, 5, 9]
see collections.Counter docs for the links to legacy versions-compatible implementations.
#SilentGhost has an excellent solution for Python 2.7+. A relatively simple solution for 2.6 and older:
a = [8, 8, 1, 1, 5, 8, 9]
popularity = sorted(set(a), key=lambda x: -a.count(x))
[8, 1, 5, 9]
This solution is, however, expensive (because of count).
Here another, better solution with temporary dictionary:
a = [8, 8, 1, 1, 5, 8, 9]
d = {}
for i in a:
d[i] = d.get(i, 0) + 1
popularity = sorted(d, key=d.get, reverse=True)