现在我有一个包含三列和多行的2D列表,每列包含一种独特的东西。第一列是UserID,第二列是时间戳,第三列是URL。该列表如下所示:
[[304070, 2015:01:01, 'http:something1'],
[304070, 2015:01:02, 'http:something2'],
[304070, 2015:01:03, 'http:something2'],
[304070, 2015:01:03, 'http:something2'],
[304071, 2015:01:04, 'http:something2'],
[304071, 2015:01:05, 'http:something3'],
[304071, 2015:01:06, 'http:something3']]
如您所见,无论userID和时间戳如何,都有一些重复的URL。
我需要提取包含唯一URL的行并将它们放入新的2D列表中。
例如,无论userID和timestamp如何,第二行,第三行,第四行和第五行都具有相同的URL。我只需要第二行(第一行出现)并将其放入我的新2D列表中。话虽这么说,第一行有一个唯一的URL,我也会把它放到我的新列表中。最后两行(第六行和第七行)具有相同的URL,我只需要第六行。
因此,我的新列表应如下所示:
[304070, 2015:01:01, 'http:something1'],
[304070, 2015:01:02, 'http:something2'],
[304071, 2015:01:05, 'http:something3']]
我想过使用这样的东西:
for i in range(len(oldList):
if oldList[i][2] not in newList:
newList.append(oldList[i])
但显然这个不起作用,因为oldList[i][2]
是一个元素,not in newList
正在检查整个2D列表,即检查每一行。像这样的代码只会创建oldList
的精确副本。
或者,我可以删除那些具有重复URL的行,因为在具有一百万行的2D列表上使用for循环加附加运算符确实需要一段时间。
答案 0 :(得分:1)
解决这个问题的一个好方法是使用set。逐个浏览一个列表列表,如果该列表尚未存在,则将该URL添加到该列表中,并将包含该URL的完整列表添加到新列表中。如果URL已在集合中,则丢弃当前列表并移至下一个列表。
old_list = [[304070, "2015:01:01", 'http:something1'],
[304070, "2015:01:02", 'http:something2'],
[304070, "2015:01:03", 'http:something2'],
[304070, "2015:01:03", 'http:something2'],
[304071, "2015:01:04", 'http:something2'],
[304071, "2015:01:05", 'http:something3'],
[304071, "2015:01:06", 'http:something3']]
new_list = []
url_set = set()
for item in old_list:
if item[2] not in url_set:
url_set.add(item[2])
new_list.append(item)
else:
pass
>>> print(new_list)
[[304070, '2015:01:01', 'http:something1'], [304070, '2015:01:02', 'http:something2'], [304071, '2015:01:05', 'http:something3']]
答案 1 :(得分:1)
>>> old_list = [[304070, "2015:01:01", 'http:something1'],
... [304070, "2015:01:02", 'http:something2'],
... [304070, "2015:01:03", 'http:something2'],
... [304070, "2015:01:03", 'http:something2'],
... [304071, "2015:01:04", 'http:something2'],
... [304071, "2015:01:05", 'http:something3'],
... [304071, "2015:01:06", 'http:something3']]
>>> temp_dict = {}
>>> for element in old_list:
... if element[2] not in temp_dict:
... temp_dict[element[2]] = [element[0], element[1], element[2]]
...
>>> temp_dict.values()
[[304070, '2015:01:01', [304070, '2015:01:02', 'http:something2'], 'http:something1'], [304071, '2015:01:05', 'http:something3']]
注意:我假设列表中不同网址的顺序并不重要。如果确实重要,请使用OrderedDict
代替默认dict
。
答案 2 :(得分:0)
您需要创建一个函数,使用url在列表中搜索项目。
def hasUrl(list, url):
for item in list:
if item[1] == url:
return True
return False
然后你的新列表创建算法应如下所示。
for i in range(len(oldList)):
if not hasUrl(newList, oldList[i][2]): # check if url is in list
newList.append(oldList[i])
此外,无需创建范围。 Python for
循环按值迭代,因此您只需编写
for item in oldList:
if not hasUrl(newList, item[2]): # check if url is not in list
newList.append(item)
答案 3 :(得分:0)
my_list = [[304070, '2015:01:01', 'http:something1'],
[304070, '2015:01:02', 'http:something2'],
[304070, '2015:01:03', 'http:something2'],
[304070, '2015:01:03', 'http:something2'],
[304071, '2015:01:04', 'http:something2'],
[304071, '2015:01:05', 'http:something3'],
[304071, '2015:01:06', 'http:something3']]
从原始列表中提取所有网址。从此列表创建一个集合,为URL生成唯一值。使用列表推导来遍历此集合,并在生成的网址列表(index
)上使用urls
来找到该网址的第一个匹配项。
最后,使用另一个列表推导与enumerate
一起选择具有匹配索引值的行。
urls = [row[2] for row in my_list]
urls_unique = set(urls)
idx = [urls.index(url) for url in urls_unique]
my_shorter_list = [row for n, row in enumerate(my_list) if n in idx]
>>> my_shorter_list
[[304070, '2015:01:01', 'http:something1'],
[304070, '2015:01:02', 'http:something2'],
[304071, '2015:01:05', 'http:something3']]