Merging values from separate dictionaries - list

Lets say I have 2 dictionaries:
dict_a = {'01A': 'X', '02B': 'V', '03C': 'AE'}
dict_b = {'01A': 'V', '02B': 'D', '03C': 'X'}
They essentially have the same keys. What I want is this:
dict_c = {'01A': ['X', 'V'], '02B': ['V', 'D'], '03C': ['AE', 'X']}
What is the proper way to do this?

There are many ways to achieve that, the one could be using defaultdict from collections something like this.
from collections import defaultdict
dict_a = {'01A': 'X', '02B': 'V', '03C': 'AE'}
dict_b = {'01A': 'V', '02B': 'D', '03C': 'X'}
d = defaultdict(list)
for d1, d2 in dict_a.items() + dict_b.items():
d[d1].append(d2)
print(dict(d))

Related

Django sub-query in Case When

I have such query
qty_used_annotation = Case(
When(scope='ticket', then=BookedTicket.objects.filter(
global_discount_code__code=F('code'), booking__status__in=['i', 'c', 'g', 'r', 's']
).count()),
When(scope='booking', then=Booking.objects.filter(
bookedticket__global_discount_code__code=F('code'),
status__in=['i', 'c', 'g', 'r', 's']
).count()),
output_field=IntegerField()
)
And it is not working. The error is Cannot resolve keyword 'code' into field.
Can somebody explain how to fix it or why it is not working.
Thanks
In subqueries you need to use OuterRef instead of F to access field from outer query:
from django.db.models import OuterRef, Subquery, Count
qty_used_annotation = Case(
When(scope='ticket', then=Subquery(BookedTicket.objects.filter(
global_discount_code__code=OuterRef('code'), booking__status__in=['i', 'c', 'g', 'r', 's']
).annotate(count=Count('id')).values('count'))),
When(scope='booking', then=Subquery(Booking.objects.filter(
bookedticket__global_discount_code__code=OuterRef('code'),
status__in=['i', 'c', 'g', 'r', 's']
).annotate(count=Count('id')).values('count'))),
output_field=IntegerField()
)

Counter in Python

Is there a way to collect values in Counter with respect to occurring number?
Example:
Let's say I have a list:
list = ['a', 'a', 'a', 'b', 'b', 'b', 'c', 'c', 'c', 'd', 'd']
When I do the Counter:
Counterlist = Counter(list)
I'll get:
Counter({'b': 3, 'a': 3, 'c': 3, 'd': 2})
Then I can select let's say a and get 3:
Counterlist['a'] = 3
But how I can select the occurring number '3'?
Something like:
Counterlist[3] = ['b', 'a', 'c']
Is that possible?
You can write the following
import collections
my_data = ['a', 'a', 'a', 'b', 'b', 'b', 'c', 'c', 'c', 'd', 'd']
result = collections.defaultdict(list)
for k, v in collections.Counter(my_data).items():
result[v].append(k)
and then access result[3] to obtain the characters with that count.

Python: out of range list for random creation of alphabet

I want to create a random alphabet. So my code is the following:
alphabet = ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z']
def new_alphabet():
for i in range(0, 26):
j = 25
my_new_alphabet = [None] * 26
my_new_alphabet[i] = alphabet[random.randint(0, j)]
alphabet.remove(my_new_alphabet[i])
j = j-1
return my_new_alphabet
print new_alphabet()
But when I try to execute it:
my_new_alphabet[i] = alphabet[random.randint(0, j)]
IndexError: list index out of range
It is probably something fairly simple but I cannot manage to find where the problem is. Thanks in advance.
There are some problems with your code.
your alphabet is missing the letter "S", so it has only 25 elements, thus the ranges for your loop and for your random indices are one-off, thus the out-of-range error
the lines j = 25 and my_new_alphabet = [None] * 26 should go before the loop, otherwise you are resetting them in each iteration
Also, you could drop j entirely and just use the bounds of the actual alphabet list instead:
def new_alphabet():
my_new_alphabet = []
while alphabet:
letter = alphabet[random.randint(0, len(alphabet) - 1)]:
# or just use this: letter = random.choice(alphabet)
alphabet.remove(letter)
my_new_alphabet.append(letter)
return my_new_alphabet
Or just use random.shuffle, which does exactly what you want:
def new_alphabet():
my_new_alphabet = list(alphabet) # copy
random.shuffle(my_new_alphabet)
return my_new_alphabet

Combinations of strings from data

So, we have data. a little big data.
example.
0 -> [a, b]
1 -> c
2 -> [d, e, f]
3 -> [g, h]
4 -> k
5 -> l
we need to combine each of this values. for this example output will be a lot of variants.
acdgkl
acdhkl
acegkl
acehkl
acfgkl
acfhkl
bcdgkl
bcdhkl
bcegkl
bcehkl
bcfgkl
bcfhkl
Quetion: what is this action procedure of combinating values called?)
and how to realize it :)
THX.
The process which turns something like
[['a','b'], ['c'], ['d', 'e', 'f'], ['g', 'h'], ['k'], ['l']]
into the sequence
[['a','c','d','g','k','l'],
['a','c','d','h','k','l'],
...
is called taking the Cartesian product. I don't think there's a name for the specific process of also concatenating the result when they're strings. (Also note that I've made each term a list, even if it's a list of one element, rather than alternating between lists (['a','b']) and scalars ('c')).
This is a common enough process that many languages have built-in support, e.g. Python:
>>> from itertools import product
>>> source = [['a','b'], ['c'], ['d', 'e', 'f'], ['g', 'h'], ['k'], ['l']]
>>> outputs = product(*source)
>>> for out in outputs:
... print(out)
...
('a', 'c', 'd', 'g', 'k', 'l')
('a', 'c', 'd', 'h', 'k', 'l')
('a', 'c', 'e', 'g', 'k', 'l')
('a', 'c', 'e', 'h', 'k', 'l')
('a', 'c', 'f', 'g', 'k', 'l')
('a', 'c', 'f', 'h', 'k', 'l')
('b', 'c', 'd', 'g', 'k', 'l')
('b', 'c', 'd', 'h', 'k', 'l')
('b', 'c', 'e', 'g', 'k', 'l')
('b', 'c', 'e', 'h', 'k', 'l')
('b', 'c', 'f', 'g', 'k', 'l')
('b', 'c', 'f', 'h', 'k', 'l')
Even if the language you're using doesn't support this natively, it's straightforward to implement.
Believe you are looking for Permutation and Combination.
Try using nested loops.
I can't comment on the comment of DSM (as I don't have enough points)
But if you want to concatenate the lists and print them as strings use
print ''.join(out)
instead of
print

How to make every combinaison of element from a list of n lists with m elements? (Python)

From a list of n lists, each having different numbers of element, I want to get all possible combinaison.
I make an example to help understand my problem:
If I have a list of lists like this:
a = [['a','b'], ['c','d'],['e','f','g']]
I would like to get something like this:
[[('a', 'c', 'e')],
[('a', 'c', 'f')],
[('a', 'c', 'g')],
[('a', 'd', 'e')],
[('a', 'd', 'f')],
[('a', 'd', 'g')],
[('b', 'c', 'e')],
[('b', 'c', 'f')],
[('b', 'c', 'g')],
[('b', 'd', 'e')],
[('b', 'd', 'f')],
[('b', 'd', 'g')]]
I get that with this:
list((zip(x,y,z) for x in a[0] for y in a [1] for z in a[2]))
Now I would like a function to do the same thing with any list of lists I pass too it. (No list is empty)
Something recursive like that can maybe work, but I have a hard time figure it out and something less complex and faster is maybe possible.
I found a solution in java here, but I don't know java and I can't translate it.
There's an itertools.product function for this. Just unpack your list as arguments:
>>> from itertools import product
>>> list(product(*a))
[('a', 'c', 'e'), ('a', 'c', 'f'), ('a', 'c', 'g'), ('a', 'd', 'e'), ('a', 'd', 'f'), ('a', 'd', 'g'), ('b', 'c', 'e'), ('b', 'c', 'f'), ('b', 'c', 'g'), ('b', 'd', 'e'), ('b', 'd', 'f'), ('b', 'd', 'g')]
from itertools import product
[[combo] for combo in product(*a)]
Yields:
[[('a', 'c', 'e')],
[('a', 'c', 'f')],
[('a', 'c', 'g')],
[('a', 'd', 'e')],
[('a', 'd', 'f')],
[('a', 'd', 'g')],
[('b', 'c', 'e')],
[('b', 'c', 'f')],
[('b', 'c', 'g')],
[('b', 'd', 'e')],
[('b', 'd', 'f')],
[('b', 'd', 'g')]]
So for a function, you just need:
def boxed_product(somelists):
return [[combo] for combo in product(*somelists)]