您可以使用 Pandas DataFrame 对象 (Pandas Dataframe Documentation),它可以以表格格式存储您的数据,类似于电子表格。在这种情况下,您的DataFrame 应该有一列来表示嵌套数据中的每个键(一列代表国家,另一列代表州,依此类推)。
Pandas DataFrames 还可以根据您对每列的记录(行)进行过滤、分组和其他有用的操作。假设您要过滤数据以仅返回德克萨斯州发生在“2018-02-01”之后的行(df 是您的DataFrame)。这可以通过以下方式实现:
df[df['State'] == 'Texas' & df['Date'] > '2018-02-01']
要构建这些DataFrame 对象,您可以从格式化为记录集合的数据开始:
data = [['USA', 'Texas', 'Austin', '2017-01-01', 169],
['USA', 'Texas', 'Austin', '2017-02-01', 231],
['USA', 'Texas', 'Houston', '2017-01-01', 265],
['USA', 'Texas', 'Houston', '2017-02-01', 310]]
然后像这样构建它们:
df = DataFrame(data, columns=['Country', 'State', 'City', 'Date', 'Value'])
如果DataFrame 对象不是一个选项,并且您不想使用嵌套循环,您还可以使用带有嵌套谓词和过滤器的列表推导式访问内部数据:
[
d[country][state][city][date]
for country in d.keys()
for state in d[country].keys()
for city in d[country][state].keys()
for date in d[country][state][city].keys()
if country == 'USA' and state == 'Texas' and city == 'Houston'
]
但是,我看不出这种方法与嵌套循环有太大区别,而且代码可读性会受到影响,恕我直言。
使用前面提到的记录集合方法 (data),而不是嵌套结构,您可以使用以下方法过滤行:
[r for r in data if r[2] == 'Houston']
为了提高可读性,您可以使用namedtuple 对象列表作为记录列表。您的数据将是:
from collections import namedtuple
record = namedtuple('Record', 'country state city date value')
data = [
record('USA', 'Texas', 'Austin', '2017-01-01', 169),
record('USA', 'Texas', 'Austin', '2017-02-01', 231),
record('USA', 'Texas', 'Houston', '2017-01-01', 265),
record('USA', 'Texas', 'Houston', '2017-02-01', 310)
]
并且您的过滤将得到改进,例如:
获取特定记录
[r for r in data if r.city == 'Houston']
返回
[
Record(country='USA', state='Texas', city='Houston', date='2017-01-01', value=265),
Record(country='USA', state='Texas', city='Houston', date='2017-02-01', value=310)
]
只获取那些特定记录的值
[r.value for r in data if r.city == 'Houston']
返回
[265, 310]
考虑到namedtuple 对象可以轻松存储它们,最后一种方法也可以处理自定义对象实例。