Input string in the python : multiple dictionaries in the list
input = [{'a': '1', 'b':'2','c':'10'},{'a': '1', 'b':'3','c':'11'},{'a':'2','b':'19','c':'100']
output = [ {'1':{'b': ('2','3'),'c':('10','11')},'2':{'b':(19),'c':(100)}}]
def dic_to_output(dic,col):
df = pd.DataFrame(dic)
colname = list(df.columns)
#print(colname)
colname.remove(str(col))
df = df.groupby('a').agg(lambda x: list(x)).reset_index().set_index('a').T
return df.to_dict()
input = [{'a': '1', 'b':'2','c':'10'},{'a': '1', 'b':'3','c':'11'},{'a':'2','b':'19','c':'100'}]
dic_to_output(dic,'a')
output:
{'1': {'b': ['2', '3'], 'c': ['10', '11']}, '2': {'b': ['19'], 'c': ['100']}}
def func(mylist):
t = {}
for i in d:
itr = iter(i)
k = i[next(itr)]
tmp = t.get(k, {})
for m in itr:
n = i[m]
if (tmp.get(m, None) == None):
tmp[m] = tuple()
if (i[m] not in set(tmp[m])):
tmp[m] += (n,)
t[k] = tmp
print([t])
d = [{'a': '1', 'b':'2','c':'10'},{'a': '1', 'b':'3','c':'11'},{'a':'2','b':'19','c':'100'}]
func(d)
d = [{'a': '1', 'b':'2','c':'10'},{'a': '1', 'b':'3','c':'11'}]
func(d)
d = [{'a': '1', 'd': 4, 'b':'2','c':'10'},{'a': '1', 'd': 4, 'b':'3','c':'11'}]
func(d)
d = [{'a': '1', 'd': 4, 'b':'2','c':'10'},{'a': '1', 'b':'3', 'd': 4,'c':'11'}]
func(d)
I have two lists in Python and I'm trying to map the values of one to the other.
List 1 (coordinates):
['7,16', '71,84', '72,48', '36,52', '75,36', '52,28', '76,44', '11,69', '56,35',
'15,21', '32,74', '88,32', '10,74', '61,34', '51,85', '10,75', '55,96',
'94,12', '34,64', '71,59', '76,75', '25,16', '54,100', '62,1', '60,85',
'16,32', '14,77', '40,78', '2,60', '71,4', '78,91', '100,98', '42,32', '37,49',
'49,34', '3,5', '42,77', '39,60', '38,77', '49,40', '40,53', '57,48', '14,99',
'66,67', '10,9', '97,3', '66,76', '86,68', '10,60', '8,87']
List 2 (index):
[3, 2, 3, 3, 3, 3, 3, 1, 3, 3, 2, 3, 1, 3, 2, 1, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3,
1, 2, 1, 3, 2, 2, 3, 3, 3, 3, 2, 2, 2, 3, 3, 3, 1, 2, 3, 3, 2, 2, 1, 1]
For the output, I need to have something like:
cluster_1: [x, y], [a,b]...
cluster_2: [c, d], [e, f]...
cluster_3: [g, h], [o, j]...
I tried doing this in a dictionary, but I can only get it to put in the last coordinate in the for loop for each value. It also always outputs keys starting from 0, and I'm looking to label them starting from 1.
for i in range(len(patients)):
# other stuff
k = 3
for b in range(k):
if cluster == (k - b):
dct['cluster_%s' % b] = patients[i]
which outputs:
{'cluster_0': '97,3', 'cluster_1': '86,68', 'cluster_2': '8,87'}
I've tried using dct['cluster_%s' % b].append(patients[i]) but I get a key error on cluster_0. Any help would be much appreciated!
You can zip your indices and coordinates, then loop over them element-wise and populate a dictionary based on the index.
clusters = {}
for idx, coord in zip(index, coords):
if idx in clusters:
clusters[idx].append(coord.split(','))
else:
clusters[idx] = [coord.split(',')]
result, where clusters[i] refers the the i-th cluster.
>>> clusters
{
3: [['7', '16'], ['72', '48'], ['36', '52'], ['75', '36'], ['52', '28'], ['76', '44'], ['56', '35'], ['15', '21'], ['88', '32'], ['61', '34'], ['94', '12'], ['71', '59'], ['25', '16'], ['62', '1'], ['16', '32'], ['71', '4'], ['42', '32'], ['37', '49'], ['49', '34'], ['3', '5'], ['49', '40'], ['40', '53'], ['57', '48'], ['10', '9'], ['97', '3']],
2: [['71', '84'], ['32', '74'], ['51', '85'], ['55', '96'], ['34', '64'], ['76', '75'], ['54', '100'], ['60', '85'], ['40', '78'], ['78', '91'], ['100', '98'], ['42', '77'], ['39', '60'], ['38', '77'], ['66', '67'], ['66', '76'], ['86', '68']],
1: [['11', '69'], ['10', '74'], ['10', '75'], ['14', '77'], ['2', '60'], ['14', '99'], ['10', '60'], ['8', '87']]
}
You could use defaultdict along with zip:
from collections import defaultdict
clusters = defaultdict(list)
for id, value in zip(cluster_indices, values):
clusters[id].append(value.split(","))
print(dict(clusters)) # {3: [['7', '16'], ['72', '48'], ...
A defaultdict can be converted to a dict with dict(clusters). However, this may not be necessary since defaultdict basically extends dict.
Note: If you need int values, then you may replace value.split(",") with [int(v) for v in value.split(",")] or list(map(int, value.split(","))). Casting them already at this point will save you an iteration later.
from collections import defaultdict
clusters = defaultdict(list)
for id, value in zip(cluster_indices, values):
clusters[id].append([int(v) for v in value.split(",")])
print(dict(clusters)) # {3: [[7, 16], [72, 48], ...
The group-by behaviour extracted to a function groupby (using a lambda function to allow any kind of transformation) so it can be reused:
from collections import defaultdict
def groupby(indices, values, map_fn):
grouped = defaultdict(list)
for id, value in zip(indices, values):
grouped[id].append(map_fn(id, value))
return dict(grouped)
clusters = groupby(cluster_indices, values, lambda _, value: value.split(","))
print(clusters) # {3: [['7', '16'], ['72', '48'], ...
Here just another way by using itertools.groupby:
from itertools import groupby
from operator import itemgetter
data = sorted(zip(cluster_indices, values), key=itemgetter(0))
grouped = groupby(data, key=itemgetter(0))
clusters = {
cluster: [value[1].split(",") for value in list(values)]
for cluster, values in grouped
}
print(clusters) # {3: [['7', '16'], ['72', '48'], ...
However, I would use the defaultdict approach above or Cory Kramer's answer as it is more simple and easier to read (and therefore preferable)!
list1 = ['19', '17']
list2 = ['18', '19', '17', '20', '23]
Here list1 size can be any length but not greater than the length of list2. The values will be one of from the list2. I want to make a new list from list2 and list1 like this.
list3 = ['0', '1', '1', '0', '0']
Here in list3, if values of list1 matches the value in list2 then it will become '1' else '0'.
Here 19 and 17 from list1 matches the values in list2 so it replaced by '1' and other replaced by '0'.
an if else statement in list comprehension can achieve this
list1 = ['19', '17']
list2 = ['18', '19', '17', '20', '23']
list3 = [1 if i in list1 else 0 for i in list2]
print(list3)
[0, 1, 1, 0, 0]
You can pass Boolean to int, iterating each item from list2:
>>> [int(v in list1) for v in list2]
[0, 1, 1, 0, 0]
For better perfromance use set since it has O(1) complexity for membership check:
>>> s = set(list1)
>>> [int(v in s) for v in list2]
[0, 1, 1, 0, 0]
Using the list comprehension offers a shorter syntax when you want to create a new list based on the values of an existing list
list_one = ["252", "252"]
list_two = ["252", "546", "253"]
[1 if i in list_two else 0 for i in list_one]
You can try this:
list3 = [1 if obj in list2 else 0 for obj in list1]
I have a string input like this:
1,2000,5,1;1,2050,5,2;2,3000,10,3
How can I split it into a list of lists like this:
[ [1, 2000, 5, 1], [1, 2050, 5, 2], [2, 3000, 10, 3], ...]
I tried regex but kept getting confused between both commas and semicolons.
Just do exactly as you said: split by semicolons and then by commas.
s = "1,2000,5,1;1,2050,5,2;2,3000,10,3"
[x.split(',') for x in s.split(';')]
#[['1', '2000', '5', '1'], ['1', '2050', '5', '2'], ['2', '3000', '10', '3']]
If you further want lists of numbers, convert the strings to numbers:
[list(map(int, x.split(','))) for x in s.split(';')]
#[[1, 2000, 5, 1], [1, 2050, 5, 2], [2, 3000, 10, 3]]
This question already has answers here:
Converting int arrays to string arrays in numpy without truncation
(6 answers)
Closed 4 years ago.
I have the following array
([[ 1, 1, 2, 2],
[ 1, 1, 3, 3],
[ 1, 1, 4, 4]])
I want to convert values from int to str, like this:
([[ '1', '1', '2', '2'],
[ '1', '1', '3', '3'],
[ '1', '1', '4', '4']])
How can I do this?
arr being your array with ints, you can do:
list(map(lambda i: list(map(str,i)), arr)) with a one liner.
The result:
[['1', '1', '2', '2'], ['1', '1', '3', '3'], ['1', '1', '4', '4']]
The following might work:
def stringify_nested_containers(obj):
if hasattr(obj, '__iter__') and not isinstance(obj, str):
obj = list(obj)
for idx in range(0, len(obj)):
obj[idx] = stringify_nested_containers(obj[idx])
else:
obj = str(obj)
return obj
Example Usage:
lyst = [
[ 1, 1, 2, 2],
[ 1, 1, 3, 3],
[ 1, 1, 4, 4]
]
slyst = stringify_nested_containers(lyst)
print(slyst)
print(type(slyst[0][0]))
Warning:
For a string named stryng, stryng[0], stryng[539], or stryng[whatever] are not characters, they are strings.
Thus,
"h" == "hello world"[0]
and
"h" == "hello world"[0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0]
Suppose you try to dig down into nested containers until you reach to an object which does not have an __iter__ method (i.e. a non-container). Suppose there is a string in your nested container. Then you will end up in an infinite recursion or loop because "a"[0] is iterable for any character "a". Specifically "a" has one element, "a"[0] and "a"[0]== "a".