英文:
Printing from [Awkward] Python Nested Dictionaries
问题
I'm just providing the translation of the non-code part of your text:
"所以,我正在学习Python(3.x),一切都很清晰,直到我遇到这个非常奇怪的字典进展,并试图更好地理解它的运作方式。我希望有人能以[简单]的方式解释它为什么会/不会起作用。
我完全意识到可能有更好的方法来做我尝试做的事情 - 所以我愿意看到并学习那些方法!
我需要提取/打印这些示例中的'this_entry'。
dict1 = {'simple':'this_entry';}
dict2 = {'key1':{'key2':'this_entry';}
dict3 = {'key1':[{'nest_key':['this is harder',['this_entry']]]}
前两个使用以下方式完全正常:
print (dict1['simple'])
print (dict2['key1']['key2'])
但第三个(显然是设计得更复杂),如果我使用:
print (dict3['key1']['nest_key'][1])
它不起作用并报错...
因此,为了调试,我从基本级别开始查看什么有效/什么无效。
print (dict3['key1']) # 显示 [{'nest_key': ['this is harder', ['hello']]}]
print (dict3['key1']['nest_key'][1]) # 在这里出错显示:
# TypeError: list indices must be integers or slices, not str
为什么会在这里出错?如果我添加一个'指针'来引用键(这是否是正确的词?),它似乎可以工作,我只是想知道为什么在这种情况下它会出错以及为什么需要这个'指针'(除了'没有它就无法正常工作')。
print (dict3['key1'][0]['nest_key'][1]) # 工作得差强人意,但显示条目['hello'],而不是hello
显然还缺少一些内容,因为输出是不正确的。我猜想理解为什么需要第一个[0]也将解释如何正确提取我所需的条目?
提前感谢!"
英文:
So, I'm learning Python (3.x) and it makes a lot of sense until I came across this very awkward progression of dictionaries and trying to get a better understanding of what it is doing. I'm hoping someone could explain in [simple] terms why it does/doesn't work.
I'm fully aware that there may be better ways of doing what I am trying to do - so I'm open to seeing and learning those too!
I need to extract/print 'this_entry' in these examples.
dict1 = {'simple':'this_entry'}
dict2 = {'key1':{'key2':'this_entry'}}
dict3 = {'key1':[{'nest_key':['this is harder',['this_entry']]}]}
The first two work absolutely fine using
print (dict1['simple'])
print (dict2['key1']['key2'])
BUT the third one is (obviously designed to be) much more tricky, if I use
print (dict3['key1']['nest_key'][1])
It doesn't work and throws up errors...
So to debug I started with the base level to see what works/what doesn't.
print (dict3['key1']) #shows [{'nest_key': ['this is harder', ['hello']]}]
print (dict3['key1']['nest_key'][1]) #breaks here showing:
#TypeError: list indices must be integers or slices, not str
Why does it break there? If I add in a 'pointer' for the key (is that even the right word?) it kinda works, I just want to know why it breaks if that isn't used and why the 'pointer' is needed in this instance (other than 'it just doesn't work without it').
print (dict3['key1'][0]['nest_key'][1]) #works-ish but shows entry ['hello'], not hello
There's something obviously missing too as the output is incorrect. I'm guessing understaning why I need the first [0] will also explain on how to extract the entry I desire properly?
Thanks in advance!
答案1
得分: 2
Here is the translated code part without the comments:
print(dict3["key1"])
[{ 'nest_key': ['this is harder', ['this_entry'] ] }]
print(dict3["key1"][0])
{ 'nest_key': ['this is harder', ['this_entry'] ] }
print(dict3["key1"][0]["nest_key"])
['this is harder', ['this_entry']]
print(dict3["key1"][0]["nest_key"][1])
['this_entry']
print(dict3["key1"][0]["nest_key"][1][0])
this_entry
英文:
With your given dict3 = {'key1':[{'nest_key':['this is harder',['this_entry']]}]}
, consider running the following statements, and the output they give:
>>> print(dict3["key1"]) # access the value of 'key1', the value is a list
[{'nest_key': ['this is harder', ['this_entry']]}]
>>> print(dict3["key1"][0]) # access the 1st elemtn of the list which is a dict
{'nest_key': ['this is harder', ['this_entry']]}
>>> print(dict3["key1"][0]["nest_key"]) # access the value of 'nest_key, the value is a list
['this is harder', ['this_entry']]
>>> print(dict3["key1"][0]["nest_key"][1]) # get 2nd element of the list, which is another list
['this_entry']
>>> print(dict3["key1"][0]["nest_key"][1][0]) # finaly get the single item in the list, value is a string
this_entry
答案2
得分: 0
dict3['key1']
- 返回一个列表- 例如
[{'nest_key': ['this is harder']}]
- 例如
dict3['key1'][0]
- 返回列表中的第一个项目- 例如
{'nest_key': ['this is harder']}
- 例如
dict3['key1'][0]['nest_key']
- 返回内部字典中的 nest_key 值- 例如
['this is harder']
- 例如
dict3['key1'][0]['nest_key'][0]
- 返回内部字典中的第一个项目- 例如 'this is harder'
dict3['key1'][0]['nest_key'][1]
- 返回内部字典中的第二个项目- 例如 ['this_entry']
dict3['key1'][0]['nest_key'][1][0]
- 返回内部字典中第二个项目中的第一个字符串- 例如 'this_entry'
dict3['key1'][0]['nest_key'][1][0][0]
- 返回内部字典中第二个项目中第一个字符串的第一个字符- 例如 't'
希望这有所帮助。
英文:
TL;DR
dict3['key1']
-> returns a list- i.e.
[{'nest_key': ['this is harder']}]
- i.e.
dict3['key1'][0]
-> returns first item in the list- i.e.
{'nest_key': ['this is harder']}
- i.e.
dict3['key1'][0]['nest_key']
-> returns the nest_key value in the inner dict- i.e.
['this is harder']
- i.e.
dict3['key1'][0]['nest_key'][0]
-> returns the first item in the inner dict- i.e.
'this is harder'
- i.e.
dict3['key1'][0]['nest_key'][1]
-> returns the 2nd item in the inner dict- i.e.
['this_entry']
- i.e.
dict3['key1'][0]['nest_key'][1][0]
-> returns the 1st string in the 2nd item in the inner dict- i.e.
'this_entry'
- i.e.
dict3['key1'][0]['nest_key'][1][0][0]
-> returns the 1st character of the 1st string in the 2nd item in the inner dict- i.e.
't'
- i.e.
In Long
Firstly, collections.defaultdict
is a good friend. https://docs.python.org/3/library/collections.html#collections.defaultdict
An example usage:
from collections import defaultdict
x = defaultdict(list)
x['key1'].append('abc')
print(x)
[out]:
defaultdict(<class 'list'>, {'key1': ['abc']})
Next if we kind of initialize the "types" of your dict3
object, it will look something like this:
In human words, dictionary of list of dictionary of list of strings or list of strings, i.e. "messy"/"awkward", see also
- https://stackoverflow.com/questions/5558418/list-of-dicts-to-from-dict-of-lists
- https://stackoverflow.com/questions/5029934/defaultdict-of-defaultdict
In Python types:
from collections import defaultdict
x = defaultdict(lambda: [defaultdict] )
x['key1'].append({'abc': 'foo bar'})
print(x)
[out]:
defaultdict(<function <lambda> at 0x7f75cebca0d0>,
{'key1': [<class 'collections.defaultdict'>, {'abc': 'foo bar'}]})
If we look at first how you can/should initialize dict3
type, you would do something like:
from collections import defaultdict
x = defaultdict(lambda: list(defaultdict(lambda: list)) )
x['key1'].append({'nest_key': ['this is harder']})
print(x)
[out]:
defaultdict(<function <lambda> at 0x7f75cee11940>,
{'key1': [defaultdict(<function <lambda>.<locals>.<lambda> at 0x7f75cf38c4c0>, {}),
{'nest_key': ['this is harder']}]})
And then to access the 'this is harder'
string you would do:
x['key1']
-> returns a list- i.e.
[{'nest_key': ['this is harder']}]
- i.e.
x['key1'][0]
-> returns first item in the list- i.e.
{'nest_key': ['this is harder']}
- i.e.
x['key1'][0]['nest_key']
-> returns the nest_key value in the inner dict- i.e.
['this is harder']
- i.e.
x['key1'][0]['nest_key'][0]
-> returns the first item in the inner dict- i.e.
'this is harder'
- i.e.
But what happens if I want dict3 = {'key1':[{'nest_key':['this is harder',['this_entry']]}]}
, where the penultimate inner most list contains a list or string?
To initialize the values, you would have done something like
from collections import defaultdict
x = defaultdict(lambda: list(defaultdict(lambda: list)) )
x['key1'].append({'nest_key': ['this is harder']})
x['key1'][0]['nest_key'].append('this is inserting a string')
x['key1'][0]['nest_key'].append(['this is inserting a list'])
print(type(x['key1'][0]['nest_key'][0])) # "this is harder" -> str
print(type(x['key1'][0]['nest_key'][1])) # "this is inserting a string" -> str
print(type(x['key1'][0]['nest_key'][2])) # ['this is inserting a list'] -> list
[out]:
<class 'str'>
<class 'str'>
<class 'list'>
To summarize the initialization:
Human words | Initialization | Usage | Outputs |
---|---|---|---|
dictionary of list | x = defaultdict(list) | x['key1'].append('abc') | {'key1': ['abc']} |
dictionary of list of dict | x = defaultdict(lambda: list(defaultdict)) | x['key1'].append({'key2':'abc'})` | {'key1': [{'key2':'abc'}]} |
dictionary of list of dict of list | x = defaultdict(lambda: list(defaultdict(lambda: list)) ) | x['key1'].append({'key2': ['foo bar']}) | defaultdict(<function <lambda> at 0x7f75cebbcc10>, {'key1': [defaultdict(<function <lambda>.<locals>.<lambda> at 0x7f75cebbc940>, {}), {'key2': ['foo bar']}]}) |
Q: Why do I bother with how the object is initialize if I just to want access an item inside?
A: If you don't know how the object is initialize, you most probably can't modify / remove / add items. And also knowing how it's initialized also helps you understand how to access the items inside.
Food for thought
If access/parsing to the item you want is kinda complicated, is there an easier way to store your data? I.e. is there a better data structure?
答案3
得分: 0
dict3['key1'] = [{'nest_key': ['this is harder', ['hello']]}]
以字典包含在数组中的形式回答
dict3['key1'][0] = {'nest_key': ['this is harder', ['hello']]}
以只有字典形式回答(nest_key: 2D数组)
dict3['key1'][0]['nest_key'] = ['this is harder', ['hello']]
以2D数组形式回答
dict3['key1'][0]['nest_key'][0] = 'this is harder', ['hello']
dict3['key1'][0]['nest_key'][0][1] = 'hello'
英文:
dict3['key1'] = [{'nest_key': ['this is harder', ['hello']]}]
#answers with a dictionary in a array
dict3['key1'][0] = {'nest_key': ['this is harder', ['hello']]}
#answers with just a dictionary (nest_key : 2D array)
dict3['key1'][0]['nest_key'] = ['this is harder', ['hello']]
#answers with 2D array
dict3['key1'][0]['nest_key'][0] = 'this is harder', ['hello']
dict3['key1'][0]['nest_key'][0][1] = 'hello'
答案4
得分: 0
Thanks to all for the answers, I have a much better understanding now and understand the terminology better too. I think this sums up what I was trying to learn:
dict3 = {'key1':[{'nest_key':['this is harder',['this_entry']]}]}
# to extract/grab/print 'this_entry'
print (dict3['key1'][0]['nest_key'][1][0])
The first part ['key1'][0] is required as it's a list with just a single element - and this is what we/I want to access. Next, to look at ['nest_key'] index 1, thus the [1], and here it has again a single element thus requiring the final index of [0].
All makes much more sense and understood where I was going wrong.
英文:
Thanks to all for the answers, I have a much better understanding now and understand the terminology better too. I think this sums up what I was trying to learn:
dict3 = {'key1':[{'nest_key':['this is harder',['this_entry']]}]}
# to extract/grab/print 'this_entry'
print (dict3['key1'][0]['nest_key'][1][0])
The first part ['key1'][0] is required as it's a list with just a single element - and this is what we/I want to access. Next, to look at ['nest_key'] index 1, thus the [1], and here it has again a single element thus requiring the final index of [0].
All makes much more sense and understood where I was going wrong.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论