Why below code giving me an error?
nested_dict = {'first':{'a':1},'second':{'b':2}}
{i for i in nested_dict.values()}
error:
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
C:\Users\ABHINA~1\AppData\Local\Temp/ipykernel_12056/1167728052.py in <module>
----> 1 {i for i in nested_dict.values()}
C:\Users\ABHINA~1\AppData\Local\Temp/ipykernel_12056/1167728052.py in <setcomp>(.0)
----> 1 {i for i in nested_dict.values()}
TypeError: unhashable type: 'dict'
You are confused about notation.
Consider these two examples:
>>> {i for i in [('a', 1), ('b', 2)]}
{('a', 1), ('b', 2)}
>>>
>>> {k: v for k, v in [('a', 1), ('b', 2)]}
{'a': 1, 'b': 2}
Using single variable i is asking for a set result.
Each element of a set must be hashable, typically immutable, like tuple, str or int.
Using the key: value notation OTOH would be asking for a dict result.
Hi actually i tried this and it works:
nested_dict = {'first':{'a':1},'second':{'b':2}}
for i in nested_dict:
for j in nested_dict[i]:
print(j)
and also this works too :
nested_dict = {'first':{'a':1},'second':{'b':2}}
for i in nested_dict.values():
print(i)
Related
I have a list of dictionaries in the form:
my_list = [{'a': 'Jane', 'b': 32}, {'a': 'Jack', 'b': 54}]
I want to re-order this to the form:
new_dt = [{'b': 32, 'a': 'Jane'}, {'b': 54, 'a': 'Jack'}]
I have used the following code:
order_dict = ['b', 'a']
for dt in my_list:
for k in order_dict:
new_dt = my_list[k]
Traceback
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
<ipython-input-87-0d451ee34800> in <module>
3 for dt in my_list:
4 for k in order_dict:
----> 5 new_dt = my_list[k]
TypeError: list indices must be integers or slices, not str
You can simply do a:
my_list = [{'a': 'Jane', 'b': 32}, {'a': 'Jack', 'b': 54}]
print([dict(sorted(x.items(),key = lambda x:x[0],reverse=True)) for x in my_list])
The OUTPUT:
[{'b': 32, 'a': 'Jane'}, {'b': 54, 'a': 'Jack'}]
Explanation
sorted(x.items(),key = lambda x:x[0],reverse=True)
Here we are just sorting the items (keys and values) in the dictionary to get the order as required.
key = lambda x:x[0]
This component ensures that we are sorting based on the first element in items(essentially the key of dictionary)
We have reverse Set to true to get the desired sequence.
def solution(l):
if 1 in l:
l.pop(l.index(1))
k=[[min(l)]]
l.pop(l.index(min(l)))
for a in l:
for index,i in enumerate(k):
if a%i[0]==0:
k[index].append(a)
else:
k.append(a)
print(k)
solution([1, 2, 3, 4, 5, 6])
My output is
if a%i[0]==0:
TypeError: 'int' object is not subscriptable
Why is this error happening? i[0] is an integer. I even printed datatype of i[0] it says it is an integer.
solution(l) takes a list and makes a list of numbers that are divisible by smaller other numbers.For above list [1,2,3,4,5,6] i want a list [[2,4,6],[3,6],[5]]
Any help is appriciated
your error is generated because you are appending to your lists of lists k an integer: k[index].append(a) on the first iteration so on the second iteration of your second inner forloop by using i[0] you are doing int_type[0]:
def solution(l):
if 1 in l:
l.pop(l.index(1))
k=[[min(l)]]
l.pop(l.index(min(l)))
for e1, a in enumerate(l):
for index,i in enumerate(k):
print('outer loop ', e1, ' inner loop ', index)
print('k = ', k)
print('i = ', i)
if a % i[0] == 0:
k[index].append(a)
else:
k.append(a)
print(k)
solution([1, 2, 3, 4, 5, 6])
output:
outer loop 0 inner loop 0
k = [[2]]
i = [2]
outer loop 0 inner loop 1
k = [[2], 3]
i = 3
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
<ipython-input-51-5da45c05c964> in <module>
15 print(k)
16
---> 17 solution([1, 2, 3, 4, 5, 6])
<ipython-input-51-5da45c05c964> in solution(l)
9 print('k = ', k)
10 print('i = ', i)
---> 11 if a % i[0] == 0:
12 k[index].append(a)
13 else:
TypeError: 'int' object is not subscriptable
The way you are using the inner for loop is not how you should do it, appending elements to your list while you are iterating may give you unexpected behavior like forever iterating and crush your program
solution(l) takes a list and makes a list of numbers that are
divisible by smaller other numbers
def solution(l):
return [[e for e in l if i%e==0] for i in l]
solution([1, 2, 3, 4, 5, 6])
# [[1], [1, 2], [1, 3], [1, 2, 4], [1, 5], [1, 2, 3, 6]]
I recently came across a python FIFO buffer example, which initialized the buffer as an empty list despite the intended input and output being of type bytes or bytearray. To my surprise this was not a mistake, and I have been left stumped as to why list.__iadd__ works in this case, but not list.__add__.
Below is code demonstrating this discrepancy (python version 3.7.4).
>>> buffer = []
>>> some_bytes = b'12345'
>>> some_bytearray = bytearray(some_bytes)
>>> buffer + some_bytes
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: can only concatenate list (not "bytes") to list
>>> buffer += some_bytes
>>> buffer
[49, 50, 51, 52, 53]
>>> buffer + some_bytearray
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: can only concatenate list (not "bytearray") to list
>>> buffer += some_bytearray
>>> buffer
[49, 50, 51, 52, 53, 49, 50, 51, 52, 53]
Edit: this same functionality also applies to other iterate types such as str, dict and tuple. Does __iadd__ attempt to mutate the argument if __add__ raises a TypeError?
List concatenation (adding) requires that both variables in the operation are lists - this (I guess) allows us to be sure of the type of object that will result from the operation. Otherwise we predict cannot the type of object that resulted from
some_list + some_set
On the other hand, extending the a list (somelist += ...) only requires that the object on the right hand side be an iterable, so that each of its elements can be added to the original list.
>>> L = []
>>> L += {1, 2, 3}
>>> L
[1, 2, 3]
>>> L += ('a', 'b', 'c')
>>> L
[1, 2, 3, 'a', 'b', 'c']
>>> L += ['x', 'y', 'z']
>>> L
[1, 2, 3, 'a', 'b', 'c', 'x', 'y', 'z']
In short, concatenation returns a new object, so the left and right and sides of the expression need to be of the same type. In-place addition mutates the original object, so the object on the left hand side need only be an iterable, its type is irrelevant.
The answer appears to be in:
a = bytearray()
help(a)
....
| __add__(self, value, /)
| Return self+value.
...
| __iadd__(self, value, /)
| Implement self+=value.
...
Thus, iadd changes the class while add does not.
I'm new at Python, and i need your help for this.
I have a user input like :
5 72 245 62
And i need to split this integers into a dictionary like this :
{1=5;2=72;3=245;4=62}
I tried something like :
sequence = dict(x ,input().split())
Where x is incrementing counter.
If your desired end result is a Python dictionary, then I think you're pretty close.
You can actually use a python builtin to achieve this called enumerate:
>>> values = input().split()
1 2 3 4
>>> values
['1', '2', '3', '4']
>>>
>>> sequence = dict(enumerate(values))
>>> sequence
{0: '1', 1: '2', 2: '3', 3: '4'}
enumerate just goes through any iterable (such as a list of strings) and outputs the index of each item and the item itself in a tuple:
>>> for x in enumerate(values):
... print(x)
...
(0, '1')
(1, '2')
(2, '3')
(3, '4')
You can then call dict on an iterable of tuples (which is what enumerate produces) in order to turn them into a dictionary.
Of course, enumerate, like most things is zero-indexed, so you can also pass in a starting number if you would like to start a 1:
>>> sequence = dict(enumerate(values, 1))
>>> sequence
{1: '1', 2: '2', 3: '3', 4: '4'}
The problem with what you have
Let's say, as above, we have a list of strings. In order to match up numbers with each string in the list, we need something like the following:
>>> dict([(1, '1'), (2, '2')...])
Notice that I am passing one argument to dict: a list of tuples where each item in the list looks like (1, '1') and I have one container holding all of them.
Your attempt was the following:
>>> sequence = dict(x ,input().split())
This is interpreted probably something like (guessing on the x):
>>> dict(1, ['1', '2', '3'])
Which produces the following Traceback:
>>> dict(1, [1, 2, 3])
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: dict expected at most 1 arguments, got 2
You are passing two arguments to dict, not one, which is what it expects.
It expects some kind of container with a bunch of things in it where the first element of each thing is mapped to the second element, such as the following:
>>> [(1, '1'), (2, '2')]
I have two dictionaries of the following structure:
a) dict1 = {'a':[ [1,2], [3,4] ], 'b':[ [1,2],[5,6] ]}
b) dict2 = {'a':[ [1,2], [5,6] ], 'b':[ [1,2],[7,8] ]}
I need to find the set difference between each key in the dictionary i.e., dict1['a'] - dict2['a'] should return [3,4]. Any thought is appreciated.
The use of mutable items (such as lists) makes the problem MUCH harder, as it precludes the simple use of Python's set data structure. It may be worth making temporary copies/versions which actually use tuples in lieu of those pesky lists:
def tempaux(d):
return dict((k, set(tuple(x) for x in v))
for k, v in d.iteritems())
Now:
def thedifs(dd1, dd2)
d1 = tempaux(dd1)
d2 = tempaux(dd2)
allkeys = set(d1).update(d2)
empty = set()
difs = []
for k in allkeys:
s1 = d1.get(k, empty)
s2 = d2.get(k, empty)
adif = s1 - s2
if adif: difs.append(adif)
return difs
This assumes actual set difference rather than symmetric difference etc. You can of course turn back the tuples into lists before returns, &c, depending on your exact requirements.
>>> s1 = set([(1,2), (3,4)])
>>> s2 = set([(1,2), (5,6)])
>>> s1 - s2
{(3, 4)}
You've got the wrong data structure for what you're trying to do.
Use this instead.
dict1 = {'a': [(1, 2), (3, 4)], 'b': [(1, 2), (5, 6)]}
dict2 = {'a': [(1, 2), (5, 6)], 'b': [(1, 2), (7, 8)]}
Life is simpler when you try to do set operations on immutable objects like tuples.
This will transform your list-of-lists into a list-of-tuples.
>>> dict( (key,[tuple(v) for v in dict1[key]]) for key in dict1 )
{'a': [(1, 2), (3, 4)], 'b': [(1, 2), (5, 6)]}
Here's the complete solution.
>>> dict1t= dict( (key,[tuple(v) for v in dict1[key]]) for key in dict1 )
>>> dict2t= dict( (key,[tuple(v) for v in dict2[key]]) for key in dict2 )
>>> set(dict1t['a'])-set(dict2t['a'])
set([(3, 4)])
applicable to list or dict or number when a and b share the same structure
c={'a':'1','b':'2'}
d={'a':'10','b':'20'}
e={'x':c,'t':15}
f={'x':d,'t':19}
def diff(a,b):
if isinstance(a, int) and isinstance(b, int):
b = b - a
return b
if isinstance(a, str) and isinstance(b, str):
if a.isdigit() and b.isdigit():
b = str(int(b) - int(a))
return b
else:
b = a
return b
if type(a) is list and type(b) is list:
for i in range(len(a)):
b[i] = diff(a[i],b[i])
return b
if type(a) is dict and type(b) is dict:
for k,v in b.iteritems():
b[k] = diff(a[k],b[k])
return b
print diff(e,f)