I have dict which got list, what I want is to display list elements in one line.
My dict
data = {'id':[1,2], 'name':['foo','bar'], 'type':['x','y']}
Expected output
name is foo and id is 1
name is bar and id is 2
My code
>>> data = {'id':[1,2], 'name':['foo','bar'], 'type':['x','y']}
>>> for key, value in data.items():
... print(value)
...
['foo', 'bar']
['x', 'y']
[1, 2]
>>>
You can use zip() as:
for name, idx in zip(data['name'], data['id']):
print(f"name is {name} and id is {idx}")
Use format() if you are using python version lower than 3.6:
for name, idx in zip(data['name'], data['id']):
print("name is {0} and id is {1}".format(name, idx))
Related
This question already has answers here:
Python group by
(9 answers)
Closed 5 months ago.
I have a list with the following structure [{key:[..,..]},...] and I am trying to group the output by the IP addresses.
my_list = [{'xxxxx1': ['123.123.123.1','hey','hello']},{'xxxxx2':['123.123.123.2','hi','HEY']},{'xxxxx3':['123.123.123.3','foo','bar']},{'xxxxx3':['123.123.123.2','foo','bar']}]
for item in my_list:
for k in item:
print(item[k])
Above code is printing the following:
['123.123.123.1', 'hey', 'hello']
['123.123.123.2', 'hi', 'HEY']
['123.123.123.3', 'foo', 'bar']
['123.123.123.2', 'foo', 'bar']
However, I am not sure how to group the output so it will look like following(notice 123.123.123.2 with two lines)
123.123.123.1
hey hello
123.123.123.2
hi HEY
foo bar
123.123.123.3
foo bar
You can make another dictionary to keep track of IP addresses. You can then iterate over the values to produce your desired output.
tracker = {}
for entry in my_list:
for k,v in entry.items():
if v[0] not in tracker.keys():
tracker[v[0]] = [v[1:]]
else:
tracker[v[0]].append(v[1:])
for k,v in tracker.items():
print(k)
for item in v:
print(item)
This produces the following output:
123.123.123.1
['hey', 'hello']
123.123.123.2
['hi', 'HEY']
['foo', 'bar']
123.123.123.3
['foo', 'bar']
Great solution from #Sterling above.
Remember, just in case you need to print it out without the brackets for the list, you can do some string concatenation in the print statement.
my_list = [
{"xxxxx1": ["123.123.123.1", "hey", "hello"]},
{"xxxxx2": ["123.123.123.2", "hi", "HEY"]},
{"xxxxx3": ["123.123.123.3", "foo", "bar"]},
{"xxxxx3": ["123.123.123.2", "foo", "bar"]},
]
tracker = {}
for entry in my_list:
for k,v in entry.items():
if v[0] not in tracker.keys():
tracker[v[0]] = [v[1:]]
else:
tracker[v[0]].append(v[1:])
for k,v in tracker.items():
print(k)
for item in v:
print(item[0] + " " + item[1])
Only one not so elegant part to get the first value of each dict:
first_values.append([i for i in item.values()][0])
It is copied from How to get the first value in a Python dictionary
Code
Simple code, for-loops and a dict. Explained with comments:
my_list = [
{'xxxxx1': ['123.123.123.1','hey','hello']},
{'xxxxx2': ['123.123.123.2','hi','HEY']},
{'xxxxx3': ['123.123.123.3','foo','bar']},
{'xxxxx3': ['123.123.123.2','foo','bar']}
]
# get the inner lists having IP as first element
first_values = []
for item in my_list:
# for each element in the list (each dict), get the first value
first_values.append([i for i in item.values()][0])
print(first_values)
# [['123.123.123.1', 'hey', 'hello'], ['123.123.123.2', 'hi', 'HEY'], ['123.123.123.3', 'foo', 'bar'], ['123.123.123.2', 'foo', 'bar']]
# convert the lists to a dict having IP as key, and words as value
ip_dict = {}
for element in first_values:
ip = element[0] # the fist element is the IP
words = element[1:] # the remaining element are words
if ip not in ip_dict.keys(): # if IP not yet added (as key)
ip_dict[ip] = words # then add the new key, value pair
else:
ip_dict[ip] += words # otherwise add the words to the existing value, which is a list of words
print(ip_dict)
# {'123.123.123.1': ['hey', 'hello'], '123.123.123.2': ['hi', 'HEY', 'foo', 'bar'], '123.123.123.3': ['foo', 'bar']}
From here you have a solid data structure as result.
The ip_dict can be pretty-printed, e.g. using a for loop like:
for ip, words in ip_dict.items():
print(f"{ip}\n{' '.join(words)}")
How can I insert for loops or if expressions inside an f-string?
I thought initially of doing something like this for if expressions:
f'{a:{"s" if CONDITION else "??"}}'
What I would like to do though is something like:
Example 1
f'{key: value\n for key, value in dict.items()}'
result:
if dict = {'a': 1, 'b': 2}
a: 1
b: 2
or Example 2
c = 'hello'
f'{c} {name if name else "unknown"}'
result:
if name exists, e.g. name = 'Mike'
hello Mike
otherwise
hello unknown
Can this be done and if yes how?
Both ternaries ("if expressions") and comprehensions ("for expressions") are allowed inside f-strings. However, they must be part of expressions that evaluate to strings. For example, key: value is a dict pair, and f"{key}: {value}" is required to produce a string.
>>> dct = {'a': 1, 'b': 2}
>>> newline = "\n" # \escapes are not allowed inside f-strings
>>> print(f'{newline.join(f"{key}: {value}" for key, value in dct.items())}')
a: 1
b: 2
Note that if the entire f-string is a single format expression, it is simpler to just evaluate the expression directly.
>>> print("\n".join(f"{key}: {value}" for key, value in dct.items())))
a: 1
b: 2
Expressions inside format strings still follow their regular semantics. For example, a ternary may test whether an existing name is true. It will fail if the name is not defined.
>>> c, name = "Hello", ""
>>> f'{c} {name if name else "unknown"}'
'Hello unknown'
>>> del name
>>> f'{c} {name if name else "unknown"}'
NameError: name 'name' is not defined
This question already has answers here:
How to count the frequency of the elements in an unordered list? [duplicate]
(33 answers)
Closed 5 years ago.
i have one list wich has names in it:
names = ['test','hallo','test']
uniquenames = ['test','hallo']
with set i get the uniquenames so the unique names are in a different list
but now i want to count how many names there are of each so test:2 hallo:1
i have this:
for i in range(len(uniquenames)):
countname = name.count[i]
but it gives me this error:
TypeError: 'builtin_function_or_method' object is not subscriptable
how can i fix that?
You could use a dictionary:
names = ['test','hallo','test']
countnames = {}
for name in names:
countnames[name] = countnames.get(name, 0) + 1
print(countnames) # => {'test': 2, 'hallo': 1}
If you want to make it case-insensitive, use this:
names = ['test','hallo','test', 'HaLLo', 'tESt']
countnames = {}
for name in names:
name = name.lower() # => to make 'test' and 'Test' and 'TeST'...etc the same
countnames[name] = countnames.get(name, 0) + 1
print(countnames) # => {'test': 3, 'hallo': 2}
In case you want the keys to be the counts, use an array to store the names in:
names = ['test','hallo','test','name', 'HaLLo', 'tESt','name', 'Hi', 'hi', 'Name', 'once']
temp = {}
for name in names:
name = name.lower()
temp[name] = temp.get(name, 0) + 1
countnames = {}
for name, count in temp.items():
countnames.setdefault(count, []).append(name)
print(countnames) # => {3: ['test', 'name'], 2: ['hallo', 'hi'], 1: ['once']}
Use Counter from collections:
>>> from collections import Counter
>>> Counter(names)
Counter({'test': 2, 'hallo': 1})
Also, for your example to work you should change names.count[i] for names.count(i) as count is a function.
I have a named tuple which I assign values to like this:
class test(object):
self.CFTs = collections.namedtuple('CFTs', 'c4annual c4perren c3perren ntfixing')
self.CFTs.c4annual = numpy.zeros(shape=(self.yshape, self.xshape))
self.CFTs.c4perren = numpy.zeros(shape=(self.yshape, self.xshape))
self.CFTs.c3perren = numpy.zeros(shape=(self.yshape, self.xshape))
self.CFTs.ntfixing = numpy.zeros(shape=(self.yshape, self.xshape))
Is there a way to loop over elements of named tuple? I tried doing this, but does not work:
for fld in self.CFTs._fields:
self.CFTs.fld= numpy.zeros(shape=(self.yshape, self.xshape))
namedtuple is a tuple so you can iterate as over normal tuple:
>>> from collections import namedtuple
>>> A = namedtuple('A', ['a', 'b'])
>>> for i in A(1,2):
print i
1
2
but tuples are immutable so you cannot change the value
if you need the name of the field you can use:
>>> a = A(1, 2)
>>> for name, value in a._asdict().iteritems():
print name
print value
a
1
b
2
>>> for fld in a._fields:
print fld
print getattr(a, fld)
a
1
b
2
from collections import namedtuple
point = namedtuple('Point', ['x', 'y'])(1,2)
for k, v in zip(point._fields, point):
print(k, v)
Output:
x 1
y 2
Python 3.6+
You can simply loop over the items as you would a normal tuple:
MyNamedtuple = namedtuple("MyNamedtuple", "a b")
a_namedtuple = MyNamedtuple(a=1, b=2)
for i in a_namedtuple:
print(i)
From Python 3.6, if you need the property name, you now need to do:
for name, value in a_namedtuple._asdict().items():
print(name, value)
Note
If you attempt to use a_namedtuple._asdict().iteritems() it will throw AttributeError: 'collections.OrderedDict' object has no attribute 'iteritems'
I have a dictionary
a = {'aaa_key': ['aaa/aaa.csv', 'aaa/aaa.csv', 'aaa.csv'], 'bbb_key': ['bbb/bbb.csv', 'bbb/bbb.csv', 'bbb.csv']}
and I want to split / signs in inner lists values.
I use this code and print gives me right values like
aaa_key [['aaa', 'aaa.csv'], ['aaa', 'aaa.csv'], ['aaa.csv']]
and
bbb_key [['bbb', 'bbb.csv'], ['bbb', 'bbb.csv'], ['bbb.csv']]
but when i try to print aa dictionary, it's lists happen to be empty {'aaa_key': [], 'bbb_key': []}. What am i doing wrong?
code sample
b = []
aa = dict()
for i in a:
for ii in a[i]:
b.append(str(ii).split('/'))
print str(i) + ' ' + str(b)
aa[i] = b
del b[:]
print aa
When you assign b to a dictionary value actually both the values and the b refer to one object and when you delete it with del b[:] actually you delete both.So you need to remove that part.
But as a more pythonic way you can simply use a dictionary comprehension to create your expected dictionary :
>>> {key:[i.split('/') for i in value] for key,value in a.items()}
{'aaa_key': [['aaa', 'aaa.csv'], ['aaa', 'aaa.csv'], ['aaa.csv']], 'bbb_key': [['bbb', 'bbb.csv'], ['bbb', 'bbb.csv'], ['bbb.csv']]}
Note that you can also reassign to a.
When you are purging the content of the list b it also purges the content of the dictionary values that was assigned from the same variable. Both the variable b and the dictionary value refers to the same list
Instead of purging the content, just associate the variable b to the reference of a new list, every time you loop in a new key.
Implementation
def foo(a):
aa = dict()
for i in a:
b = []
for ii in a[i]:
b.append(str(ii).split('/'))
aa[i] = b
return aa
Sample Run
>>> foo(a)
{'aaa_key': [['aaa', 'aaa.csv'], ['aaa', 'aaa.csv'], ['aaa.csv']], 'bbb_key': [['bbb', 'bbb.csv'], ['bbb', 'bbb.csv'], ['bbb.csv']]}