Printing from [Awkward] Python Nested Dictionaries

huangapple go评论64阅读模式
英文:

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']}]
  • dict3['key1'][0] -> returns first item in the list
    • i.e. {'nest_key': ['this is harder']}
  • dict3['key1'][0]['nest_key'] -> returns the nest_key value in the inner dict
    • i.e. ['this is harder']
  • dict3['key1'][0]['nest_key'][0] -> returns the first item in the inner dict
    • i.e. 'this is harder'
  • dict3['key1'][0]['nest_key'][1] -> returns the 2nd item in the inner dict
    • i.e. ['this_entry']
  • dict3['key1'][0]['nest_key'][1][0] -> returns the 1st string in the 2nd item in the inner dict
    • i.e. 'this_entry'
  • 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'

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

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']}]
  • x['key1'][0] -> returns first item in the list
    • i.e. {'nest_key': ['this is harder']}
  • x['key1'][0]['nest_key'] -> returns the nest_key value in the inner dict
    • i.e. ['this is harder']
  • x['key1'][0]['nest_key'][0] -> returns the first item in the inner dict
    • i.e. 'this is harder'

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 = {&#39;key1&#39;:[{&#39;nest_key&#39;:[&#39;this is harder&#39;,[&#39;this_entry&#39;]]}]}
# to extract/grab/print &#39;this_entry&#39;
print (dict3[&#39;key1&#39;][0][&#39;nest_key&#39;][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.

huangapple
  • 本文由 发表于 2023年3月20日 23:32:26
  • 转载请务必保留本文链接:https://go.coder-hub.com/75792269.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定