I'm trying to get all possible strings from the values in a dictionary given a particular key. For example, 'A' could mean either 'aaa','aba', or 'aac' and 'B' could mean either 'bbb','bab', or 'bbc', etc.
I've given an example of the output where it shows most combinations of the possible strings
import itertools
in_ = 'ABC'
D = {'A':['aaa','aba','aac'],'B':['bbb','bab','bbc'],'C':['ccc','cac','ccb']}
#out_ = ['aaabbbccc','ababbbccc','aacbbbccc','aaababccc','aaabbcccc','aaabbbcac','aaabbbccb'...]
I started writing the code but it started to get REALLY messy and I feel that there is a way to use itertools or something more pythonic to achieve this goal
output = []
for char in in_:
out_string = ''
while char:
for v in D[char]:
while v:
for char2 in in_:
out_string
#not pythonic . . .
Well, you've got itertools imported there. Let's use it! We want to take the Cartesian product D['A'] × D['B'] × D['C'], so we'll do precisely that using itertools.product.
import itertools
in_ = 'ABC'
D = {'A':['aaa','aba','aac'],'B':['bbb','bab','bbc'],'C':['ccc','cac','ccb']}
iterables = [D[character] for character in in_]
out_ = [''.join(tup) for tup in itertools.product(*iterables)]
Now, out_ is:
['aaabbbccc', 'aaabbbcac', 'aaabbbccb', 'aaababccc', 'aaababcac', 'aaababccb',
'aaabbcccc', 'aaabbccac', 'aaabbcccb', 'ababbbccc', 'ababbbcac', 'ababbbccb',
'abababccc', 'abababcac', 'abababccb', 'ababbcccc', 'ababbccac', 'ababbcccb',
'aacbbbccc', 'aacbbbcac', 'aacbbbccb', 'aacbabccc', 'aacbabcac', 'aacbabccb',
'aacbbcccc', 'aacbbccac', 'aacbbcccb']
Is that the result you were going for?
Related
Given this string:
fsw="M525x617M525x617S16d48492x577S10000505x544S22a00506x524S21300487x601S37601511x574S34500482x483
I'd like to convert
fsw[8:] (thus "M525x617S16d48492x577S10000505x544S22a00506x524S21300487x601S37601511x574S34500482x483")
in a dictionary containing:
{'S16d48':'492x577', 'S10000':'505x544', 'S22a00':'506x524', 'S21300':'487x601', 'S37601':'511x574', 'S34500':'482x483'}
I managed to get the following with regexp:
>>> import re
>>> re.findall("S[123][0-9a-f]{2}[0-5][0-9a-f]",fsw[8:])
['S16d48', 'S10000', 'S22a00', 'S21300', 'S37601', 'S34500']
>>> re.findall("S[123][0-9a-f]{2}[0-5][0-9a-f].......",fsw[8:])
['S16d48492x577', 'S10000505x544', 'S22a00506x524', 'S21300487x601', 'S37601511x574', 'S34500482x483']
but as far as a dictionary is concerned... I failed to get any further.
Another question: in a Python dictionary it is well the whole
key-value pair (say "S16d48":"492x577") that must be unique right ?
In advance - thanks a lot.
Regards.
It seems you can alter your expression to
(?P<key>S[123][0-9a-f]{2}[0-5][0-9a-f])
(?P<value>\d+x\d+)
And then do a dict comprehension as in
import re
rx = re.compile(r'(?P<key>S[123][0-9a-f]{2}[0-5][0-9a-f])(?P<value>\d+x\d+)')
data = "M525x617M525x617S16d48492x577S10000505x544S22a00506x524S21300487x601S37601511x574S34500482x483"
result = {m["key"]: m["value"] for m in rx.finditer(data)}
This yields
{'S16d48': '492x577', 'S10000': '505x544', 'S22a00': '506x524', 'S21300': '487x601', 'S37601': '511x574', 'S34500': '482x483'}
See a demo for the expression on regex101.com and for the code on ideone.com.
You can convert the lists you already created to a dictionary in the following way:
import re
fsw="M525x617M525x617S16d48492x577S10000505x544S22a00506x524S21300487x601S37601511x574S34500482x483"
str_lst = re.findall("S[123][0-9a-f]{2}[0-5][0-9a-f]",fsw[8:])
full_lst = re.findall("S[123][0-9a-f]{2}[0-5][0-9a-f].......",fsw[8:])
str_dict = {x: y[len(x):] for x in str_lst for y in full_lst if y.startswith(x)}
This gives:
{'S16d48': '492x577',
'S10000': '505x544',
'S22a00': '506x524',
'S21300': '487x601',
'S37601': '511x574',
'S34500': '482x483'}
Not sure if I have understood what you are trying to do, but one way to obtain your dictionary from that string is
d = {}
for piece in fsw[8:].split('S')[1:]:
d["S"+piece[:5]] = piece[5:]
print(d)
I think this is a basic question, but I want to know this.
For example, in the below situation:
str1 = {}
str1['a'] = 1
str1['b'] = 2
I want to access to the following value:
str1['a'][0]
I think i've solved it.
I could use it this way. when i got a key, check the key and can make a list.
Sorry for confusing..
import sys
key='a'
str1={}
if 'a' in str1.keys():
str1['a'].append(0)
else:
str1 = {key : list()}
str1['a'].append(0)
print(str1['a'][0])
str1['a'].append(3)
print(str1['a'])
Sang Yoon Kim;
I think you might be confusing nested lists with Dictionaries
Dictionary is a key value pair.
Take a look at this;
L = [1,2,3] ----> L[0] = 1
G = [[1,2,3],[4,5,6]]
Now G[1] gives a list [4,5,6]
to access the element 6 , do G[1][2]
Dictionaries are entirely different
Please take a look at these links;
https://www.geeksforgeeks.org/python-list/
https://www.geeksforgeeks.org/python-dictionary/
To answer you question, you cannot access str['a][0] because its an invalid operation.
I think i've solved it. I could use it this way. when i got a key, check the key and can make a list. Sorry for confusing..
import sys
key='a'
str1={}
if 'a' in str1.keys():
str1['a'].append(0)
else:
str1 = {key : list()}
str1['a'].append(0)
print(str1['a'][0])
str1['a'].append(3)
print(str1['a'])
I have a dataframe which contains the below column:
column_name
CUVITRU 8 gram
CUVITRU 1 grams
I want to replace these gram and grams to gm. So I have created a dictionary
dict_ = {'gram':'gm','grams':'gm'}
I am able to replace it but it is converting grams to gms. Below is the column after conversion:
column_name
CUVITRU 8 gm
CUVITRU 1 gms
How can I solve this issue.
Below is my code:
dict_ = {'gram':'gm','grams':'gm'}
for key, value in dict_abbr.items():
my_string = my_string.replace(key,value)
my_string = ' '.join(unique_list(my_string.split()))
def unique_list(l):
ulist = []
[ulist.append(x) for x in l if x not in ulist]
return ulist
because it finds 'gram' in 'grams', one way is to instead of string use reg exp for replacement on word boundaries, like (r"\b%s\.... look at the answer usign .sub here for example: search-and-replace-with-whole-word-only-option
You don't actually care about the dict; you care about the key/value pairs produced by its items() method, so just store that in the first place. This lets you specify the order of replacements to try regardless of your Python version.
d = [('grams':'gm'), ('gram':'gm')]
for key, value in d:
my_string = my_string.replace(key,value)
You can make replacements in the reverse order of the key lengths instead:
dict_ = {'gram':'gm','grams':'gm'}
for key in sorted(dict_abbr, key=len, reverse=True):
my_string = my_string.replace(key, dict_[key])
Put the longer string grams before the shorter one gram like this {'grams':'gm','gram':'gm'}, and it will work.
Well, I’m using a recent python 3 like 3.7.2 which guarantees that the sequence of retrieving items is the same as that they are created in the dictionary. For earlier Pythons that may happen (and this appears to be the problem) but isn’t guaranteed.
Let's say I have such a list:
['word_4_0_w_7',
'word_4_0_w_6',
'word_3_0_w_10',
'word_3_0_w_2']
and I want to sort them according to number that comes after "word" and according to number after "w".
It will look like this:
['word_3_0_w_2',
'word_3_0_w_10',
'word_4_0_w_6',
'word_4_0_w_7']
What comes in mind is to create a bunch of list and according to index after "word" stuff them with sorted strings according "w", and then merge them.
Is in Python more clever way to do it?
Use Python's key functionality, in conjunction with other answers:
def mykey(value):
ls = value.split("_")
return int(ls[1]), int(ls[-1])
newlist = sorted(firstlist, key=mykey)
## or, if you want it in place:
firstlist.sort(key=mykey)
Python will be more efficient with key vs cmp.
You can provide a function to the sort() method of list objects:
l = ['word_4_0_w_7',
'word_4_0_w_6',
'word_3_0_w_10',
'word_3_0_w_2']
def my_key_func(x):
xx = x.split("_")
return (int(xx[1]), int(xx[-1]))
l.sort(key=my_key_func)
Output:
print l
['word_3_0_w_2', 'word_3_0_w_10', 'word_4_0_w_6', 'word_4_0_w_7']
edit: Changed code according to comment by #dwanderson ; more info on this can be found here.
You can use a function to extract the relevant parts of your string and then use those parts to sort:
a = ['word_4_0_w_7', 'word_4_0_w_6', 'word_3_0_w_10', 'word_3_0_w_2']
def sort_func(x):
parts = x.split('_');
sort_key = parts[1]+parts[2]+"%02d"%int(parts[4])
return sort_key
a_sorted = sorted(a,key=sort_func)
The expression "%02d" %int(x.split('_')[4]) is used to add a leading zero in front of second number otherwise 10 will sort before 2. You may have to do the same with the number extracted by x.split('_')[2].
my situation is as follows:
I have a large table like object which is accessed with a string key and integer index; i.e. lookup is like this: value = table.get("Key", index) .
I would like to give the user the opportunity to enter an arbitrary algebraic expression involving the string keys. The code code should then iterate over the second index and evaluate the expression repeatedly.
So for user input like this: "KeyA + 2*math.abs(KeyC)" I would like to run python code resembling:
for index in index_list:
answer = table.get("KeyA", index) + 2*math.abs(table.get("Keyc",index))
I guess can parse the expression using one of the Python Parser libraries I found on the internet, but it is not by any means clear to me how actually "run" the parsed code. Any suggestions?
If your end users can enter variables in figure brackets, {..}, you can use str.format to format your string
>>> expression = '{a}*{b}'
>>> values = {'a': 10, 'b': 20, 'c': 30}
>>> expression.format(**values)
'10*20'
Here values dictionary might be filled with table.get for all keys found in expression, for example with a regular expression:
>>> import re
>>> regexp = re.compile('{(.*?)}')
>>> keys = regexp.findall(expression)
>>> keys
['a', 'b']
>>> table_get = lambda *x: np.random.randint(5)
>>> values = {k: table_get(k) for k in keys}
>>> expression.format(**values)
'1*4'
Then you can refer to Safe way to parse user-supplied mathematical formula in Python for safe expression parsing and evaluation.