从 namedtuple 记录结构中检索数据失败
Retrieving data from namedtuple record structure fails
我需要创建一个查找 table 来存储表格数据并根据多个字段值检索记录。
我找到了一个示例 post # 15418386,它几乎可以满足我的需要,但是无论传递的参数如何,它总是 returns 相同的记录。
我在这个 post 的底部列出了代码,在 casr 中 link 不起作用。
我已经通过使用 IDE 中的调试器(我使用的是 PyCharm)验证了文件被正确读取并且数据 table 也被正确填充。 =14=]
代码中包含的测试数据为:
name,age,weight,height
Bob Barker,25,175,6ft 2in
Ted Kingston,28,163,5ft 10in
Mary Manson,27,140,5ft 6in
Sue Sommers,27,132,5ft 8in
Alice Toklas,24,124,5ft 6in
函数总是returns最后一条记录,我相信问题出在这几行代码中。但是我不明白它是如何工作的。
matches = [self.records[index]
for index in self.lookup_tables[field].get(value, []) ]
return matches if matches else None
我想了解代码应该如何工作,以便我可以编辑它以便能够搜索多个参数。
原码:
from collections import defaultdict, namedtuple
import csv
class DataBase(object):
def __init__(self, csv_filename, recordname):
# read data from csv format file int list of named tuples
with open(csv_filename, 'rb') as inputfile:
csv_reader = csv.reader(inputfile, delimiter=',')
self.fields = csv_reader.next() # read header row
self.Record = namedtuple(recordname, self.fields)
self.records = [self.Record(*row) for row in csv_reader]
self.valid_fieldnames = set(self.fields)
# create an empty table of lookup tables for each field name that maps
# each unique field value to a list of record-list indices of the ones
# that contain it.
self.lookup_tables = defaultdict(lambda: defaultdict(list))
def retrieve(self, **kwargs):
"""Fetch a list of records with a field name with the value supplied
as a keyword arg ( or return None if there aren't any)."""
if len(kwargs) != 1:
raise ValueError(
'Exactly one fieldname/keyword argument required for function '
'(%s specified)' % ', '.join([repr(k) for k in kwargs.keys()])
)
field, value = kwargs.items()[0] # get only keyword arg and value
if field not in self.valid_fieldnames:
raise ValueError('keyword arg "%s" isn\'t a valid field name' % field)
if field not in self.lookup_tables: # must create field look up table
for index, record in enumerate(self.records):
value = getattr(record, field)
self.lookup_tables[field][value].append(index)
matches = [self.records[index]
for index in self.lookup_tables[field].get(value, []) ]
return matches if matches else None
if __name__ == '__main__':
empdb = DataBase('employee.csv', 'Person')
print "retrieve(name='Ted Kingston'):", empdb.retrieve(name='Ted Kingston')
print "retrieve(age='27'):", empdb.retrieve(age='27')
print "retrieve(weight='150'):", empdb.retrieve(weight='150')
变量 value
在以下 if .. for ..
块中被覆盖:
field, value = kwargs.items()[0] # <--- `value` defined
...
if field not in self.lookup_tables:
for index, record in enumerate(self.records):
value = getattr(record, field) # <--- `value` overwritten
self.lookup_tables[field][value].append(index)
所以,value
指的是最后一条记录的值。您需要使用其他名称以防止此类覆盖。
if field not in self.lookup_tables:
for index, record in enumerate(self.records):
v = getattr(record, field)
self.lookup_tables[field][v].append(index)
我需要创建一个查找 table 来存储表格数据并根据多个字段值检索记录。
我找到了一个示例 post # 15418386,它几乎可以满足我的需要,但是无论传递的参数如何,它总是 returns 相同的记录。 我在这个 post 的底部列出了代码,在 casr 中 link 不起作用。
我已经通过使用 IDE 中的调试器(我使用的是 PyCharm)验证了文件被正确读取并且数据 table 也被正确填充。 =14=]
代码中包含的测试数据为:
name,age,weight,height
Bob Barker,25,175,6ft 2in
Ted Kingston,28,163,5ft 10in
Mary Manson,27,140,5ft 6in
Sue Sommers,27,132,5ft 8in
Alice Toklas,24,124,5ft 6in
函数总是returns最后一条记录,我相信问题出在这几行代码中。但是我不明白它是如何工作的。
matches = [self.records[index]
for index in self.lookup_tables[field].get(value, []) ]
return matches if matches else None
我想了解代码应该如何工作,以便我可以编辑它以便能够搜索多个参数。
原码:
from collections import defaultdict, namedtuple
import csv
class DataBase(object):
def __init__(self, csv_filename, recordname):
# read data from csv format file int list of named tuples
with open(csv_filename, 'rb') as inputfile:
csv_reader = csv.reader(inputfile, delimiter=',')
self.fields = csv_reader.next() # read header row
self.Record = namedtuple(recordname, self.fields)
self.records = [self.Record(*row) for row in csv_reader]
self.valid_fieldnames = set(self.fields)
# create an empty table of lookup tables for each field name that maps
# each unique field value to a list of record-list indices of the ones
# that contain it.
self.lookup_tables = defaultdict(lambda: defaultdict(list))
def retrieve(self, **kwargs):
"""Fetch a list of records with a field name with the value supplied
as a keyword arg ( or return None if there aren't any)."""
if len(kwargs) != 1:
raise ValueError(
'Exactly one fieldname/keyword argument required for function '
'(%s specified)' % ', '.join([repr(k) for k in kwargs.keys()])
)
field, value = kwargs.items()[0] # get only keyword arg and value
if field not in self.valid_fieldnames:
raise ValueError('keyword arg "%s" isn\'t a valid field name' % field)
if field not in self.lookup_tables: # must create field look up table
for index, record in enumerate(self.records):
value = getattr(record, field)
self.lookup_tables[field][value].append(index)
matches = [self.records[index]
for index in self.lookup_tables[field].get(value, []) ]
return matches if matches else None
if __name__ == '__main__':
empdb = DataBase('employee.csv', 'Person')
print "retrieve(name='Ted Kingston'):", empdb.retrieve(name='Ted Kingston')
print "retrieve(age='27'):", empdb.retrieve(age='27')
print "retrieve(weight='150'):", empdb.retrieve(weight='150')
变量 value
在以下 if .. for ..
块中被覆盖:
field, value = kwargs.items()[0] # <--- `value` defined
...
if field not in self.lookup_tables:
for index, record in enumerate(self.records):
value = getattr(record, field) # <--- `value` overwritten
self.lookup_tables[field][value].append(index)
所以,value
指的是最后一条记录的值。您需要使用其他名称以防止此类覆盖。
if field not in self.lookup_tables:
for index, record in enumerate(self.records):
v = getattr(record, field)
self.lookup_tables[field][v].append(index)