我仍然只有几个月进入python,所以请原谅丑陋的代码。我有一个由唯一ID组成的数据集。考虑这种格式为3行,每行3个ID' s:
zList = [[1412,2521,53522],
[52632,1342,1453],
[3413,342,25232]]
我试图用一些相应的数据(名字,姓氏,州等)替换每个ID。理想输出如下:
resultList = [[Bob, Smith, Ohio, Jane, Doe, Texas, John, Smith, Alaska],
[Jim, Bob, California, Jack, White, Virginia, John, Smith, Nevada],
[Hank, Black, Kentucy, Sarah, Hammy, Florida, Joe, Blow, Mississipi]]
我意识到在结果中添加新维度会更清晰,因为我实际上是将每个ID扩展到新列表中。我避免这样做是因为我认为保持平坦会更容易,而且我担心在2维上迭代任何东西!愿意考虑所有选择......
我用来匹配的数据是你可能期望的:
matchData = [[1412, Bob, Smith, Ohio, lots of additional data],
[2521, Jane, Doe, Texas, Lots of Additional Data],
[3411], Jim, Black, New York, Lots of Additional Data],
[...etc...]]
以下是我尝试过的方法:
resultList = []
for i, valz in enumerate(zList):
for j, ele in enumerate(valz):
check = False
for k, valm in enumerate(matchData):
if ele == valm[0]:
resultList.append(valm)
check = True
break
if check == False:
print "error during rebuild"
pprint.pprint(resultList, width=400)
现在虽然它几乎可以运作,但它缺少了两个我无法解决的关键事项。弄清楚。我的代码将所有内容转储到一个大列表中。我必须能够保持原始数据集的顺序和逻辑分离。 (记住,原始数据集是3行3 ID')。
如果找不到匹配项,我还需要抛出错误。您可以在上面的代码中看到我的尝试,但它无法正常工作。我尝试在第一个if语句之后添加它:
elif all(ele not in valm[15):
check = False
但是我收到了这个错误:"TypeError: argument of type 'int' is not iterable"
答案 0 :(得分:0)
我认为你的主要问题是构建列表。从它看起来,你有3"条目" zList中的每行和resultList中的每行。我建议将zList更改为一维列表,并将结果列表中的不同条目放入其自己的列表中(在resultList内部如此:
zList = [ 1412, 2521, 53522, 52632, 1342, 1453, 3413, 342, 25232 ]
resultList = [[ "Bob", "Smith", "Ohio" ],[ "Jane", "Doe", "Texas" ],[ "John", "Smith", "Alaska" ],
[ "Jim", "Bob", "California" ],[ "Jack", "White", "Virginia" ],[ "John", "Smith", "Nevada" ],
[ "Hank", "Black", "Kentucy" ],[ "Sarah", "Hammy", "Florida" ],[ "Joe", "Blow", "Mississipi"]]
现在您可以检查两个列表的长度是否相同(在这种情况下为9):
>>> len(zList) == len(resultList
True
>>> len(zList)
9
从这里,您可以使用词典或列表。作为一名新手程序员,您可能还不熟悉词典,所以请查看the documentation。
<强>列表:强>
只需遍历列表的长度,将其添加到新列表中,然后将新列表附加到输出列表中,如下所示:
zList = [...]
resultList = [[...]]
matchList = [] #or whatever you want to call it
for i in range(len(zList)): #the index is needed, you can also use enumerate
element_list = []
element_list.append(zList[i]) #note zList[i] = 2nd iterator of enumerate
for j in resultList[i]: #the index is not needed, so use the value
element_list.append(j)
matchList.append(elementList)
>>> print matchList
[1412, 'Bob', 'Smith', 'Ohio']
[2521, 'Jane', 'Doe', 'Texas']
[53522, 'John', 'Smith', 'Alaska']
[52632, 'Jim', 'Bob', 'California']
[1342, 'Jack', 'White', 'Virginia']
[1453, 'John', 'Smith', 'Nevada']
[3413, 'Hank', 'Black', 'Kentucy']
[342, 'Sarah', 'Hammy', 'Florida']
[25232, 'Joe', 'Blow', 'Mississipi'] #split in separate lines for clarity here
要添加更多数据,只需增加resultList中列表的大小,以便添加以下作业:
resultList = [[ "Bob", "Smith", "Ohio", "Tech Support" ], ...
<强>字典强>
我认为这是更简单的方法。只需创建一个dict,然后使用zList中的元素与resultList中的相应元素一起形成键作为条目,如下所示:
matchDict = {}
for n in range(len(zList)): #need the index, remember?
matchDict[zList[n]] = resultList[n]
>>> print matchDict
{ 1412 : ['Bob', 'Smith', 'Ohio'] ,
1453 : ['John', 'Smith', 'Nevada'] ,
25232 : ['Joe', 'Blow', 'Mississipi'] ,
53522 : ['John', 'Smith', 'Alaska'] ,
3413 : ['Hank', 'Black', 'Kentucy'] ,
342 : ['Sarah', 'Hammy', 'Florida'] ,
52632 : ['Jim', 'Bob', 'California'] ,
2521 : ['Jane', 'Doe', 'Texas'] ,
1342 : ['Jack', 'White', 'Virginia'] }
*注意,您可以使用键调用词典中的元素,因此print matchDict [1412] - &gt; [&#34; Bob&#34;,&#34; Smith&#34;,&#34; Ohio&#34;]。同样,您可以通过向resultList添加更多信息来扩展数据,如上所示。
答案 1 :(得分:0)
要获得更清晰的代码,您应该考虑使用类来封装数据。
让我们看看:
class Person(object):
def __init__(self, identifier, firstname, name, state):
self.id = identifier
self.firstname = firstname
self.name = name
self.state = state
def __repr__(self):
return "<{0} {1} (id : {2}) living in {3}>".format(self.firstname, self.name, self.id, self.state)
def as_list(self):
return [self.firstname, self.name, self.state]
class PersonList(list):
def __init__(self, *args, **kwargs):
list.__init__(self, *args, **kwargs)
def getById(self, identifier):
""" return the person of this list whose the id is equals to the requested identifier. """
# filter(boolean function, iterable collection) -> return a collection hat contain only element that are true according to the function.
# here it is used a lambda function, a inline function declaration that say for any given object x, it return x.id == identifier.
# the list is filtered to only get element with attribut id equals to identifier. See https://docs.python.org/3.4/library/functions.html#filter
tmp = list(filter(lambda x: x.id == identifier, self))
if len(tmp)==0:
raise Exception('Searched for a Person whose id is {0}, but no one have this id.'.format(identifier))
elif len(tmp) > 1:
raise Exception('Searched for a Person whose id is {0}, and many people seem to share this id. id are supposed to be unique.'.format(identifier))
return tmp[0]
##CONSTANTS##
#id list - modified to not instanciate 9 Person
ids = [[1412,2521,3411],#bob, jane, jim
[3411,1412,1412],#jim, bob, bob
[3411,2521,2521]]#jim, jane, jane
#person list
index=PersonList([Person(1412, 'Bob', 'Smith', 'Ohio'),
Person(2521, 'Jane', 'Doe', 'Texas'),
Person(3411, 'Jim', 'Black', 'New York')])
def computeResult(id_list, personList):
personList = [ [personList.getById(identifier) for identifier in subList] for subList in id_list]
resultList= []
for sublist in personList:
tmp = []
for person in sublist:
tmp += person.as_list()
resultList.append(tmp)
return resultList
if __name__ == "__main__":
print(computeResult(ids, index))
一方面,在我看来,由于使用了错误的数据结构,代码更难编写。应用程序应该处理Person对象而不是string列表列表。无论如何,这是你的应用程序。我建议您考虑使用personList
作为更好的数据结构来处理您的数据,而不是这个丑陋的列表列表。
另一方面,如果我认为id是唯一的,那么如果你成功将数据放入字典中,例如
index={1412 : Person(...), 2500 : Person(...), ...}
或
index={1412: ['Bob', 'Doe', ...], 2500 : [...], ...}`
它会更加实用,因为您可以删除PersonList
类,只使用index.get(1412)
来获取与id对应的数据。
编辑:按要求添加跟踪示例。
此脚本保存在名为“sof.py”
的文件中python3
>>> import sof
>>> sof.index
[<Bob Smith (id : 1412) living in Ohio>, <Jane Doe (id : 2521) living in Texas>, <Jim Black (id : 3411) living in New York>]
>>> sof.index.getById(666)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/home/vaisse/Bureau/sof.py", line 25, in getById
raise Exception('Searched for a Person whose id is {0}, but no one have this id.'.format(identifier))
Exception: Searched for a Person whose id is 666, but no one have this id.
正如您所看到的,如果出现错误,一切都会停止。如果此行为不是您想要的行为,您还可以返回None
值并在失败的地方保留跟踪而不是升起Exception
,然后继续处理数据。如果您希望应用程序在出现错误时仍然运行,您应该查看https://docs.python.org/3.1/library/warnings.html。否则简单的异常提升就足够了