我需要检查某个对象中是否存在某些item
(可以正常工作:list
,set
,dict
,collection
。 ..)并从该对象获取数据。
我发现的最好方法是构建一个dict
key
和value
:
known={}
for item in list:
if item in known:
item = known[item]
else
known[item] = item
foo(item)
list
的另一种方式(但非常慢):
known=[]
for item in list:
if not item in known:
known.insert(0, item)
else:
item = known[known.index(item)]
foo(item)
最后一个有set():
known = set()
for item in list:
if item in known:
item = next(i for i in known if i == item)
else:
known.add(item)
foo(item)
看起来很荒谬吗?我想不出一个简单的方法,没有丑陋的黑客,性能损失和/或内存使用。
我正在构建这些可恶的原因而不是:
for item in list:
foo(item)
items
list
内的a == b
是大字符串,其中大多数是相同的(在a is b
的感觉中),但不相同,(foo()
意义上的$a0
1}})。我需要节省内存使用。所以我想在主对象中添加一个唯一的项目,并只将该项目的引用发送到50
如果有良好的性能/内存/可读性妥协,我怎么能这样做?
答案 0 :(得分:2)
如果我理解正确,那么您正在寻找一种方法来映射比较等于单个唯一实例的字符串。在这种情况下,请考虑使用intern
内置函数。 intern
将字符串放入Python的内部“interned string”映射中,并返回该字符串的唯一实例。只要您需要一个唯一的实例,就可以在字符串上调用intern
。
演示:
>>> s1 = "a"
>>> s2 = "b"
>>> s3 = "ab"
>>> s4 = s1 + s2
>>> id(s3)
4300082912
>>> id(s4)
4300081472
>>> s5 = intern(s3)
>>> id(s5)
4300082912
>>> id(intern(s4))
4300082912
演示2(Python 2):
>>> arr = [str(x // 2) for x in range(1000, 1010)]
>>> arr
['500', '500', '501', '501', '502', '502', '503', '503', '504', '504']
>>> map(id, arr) # all strings in arr are distinct
[4300081512, 4300081552, 4300081592, 4300081672, 4300081712, 4300081752, 4300081792, 4300081832, 4300081872, 4300081912]
>>> arr2 = map(intern, arr)
>>> arr2
['500', '500', '501', '501', '502', '502', '503', '503', '504', '504']
>>> map(id, arr2) # equal strings are identical now
[4300079632, 4300079632, 4300081592, 4300081592, 4300081712, 4300081712, 4300081792, 4300081792, 4300081872, 4300081872]
答案 1 :(得分:0)
使用dict
很好,但您可以使用setdefault
。演示设置:
>>> items = [str(i//2) for i in range(6)]
>>> items
['0', '0', '1', '1', '2', '2']
>>> list(map(id, items))
[55450176, 55450240, 55450208, 55450272, 55450304, 55450336]
为每个值使用第一个对象:
>>> firsts = map({}.setdefault, items, items)
演示它有效:
>>> list(map(id, firsts))
[55450176, 55450176, 55450208, 55450208, 55450304, 55450304]
答案 2 :(得分:0)
如何使用套装:
fn
输出:
lst = ['huge string1', 'huge string1','huge string1','huge string1', 'huge string2', 'huge string2','huge string2','huge string2']
print(lst)
print(set(lst))