【发布时间】:2015-06-24 15:40:28
【问题描述】:
例如:x=[1,1,1,1,2,2,2,"a","a","a","b","b"]
我想打印:1,2,"a","b"
如果列表很长,我什至不知道列表中有多少种元素怎么办?
Python中有没有可以做到这一点的函数?或者,我该如何编写一个 for 循环来做到这一点?
【问题讨论】:
-
你想保持元素的顺序吗?
标签: python list python-2.7
例如:x=[1,1,1,1,2,2,2,"a","a","a","b","b"]
我想打印:1,2,"a","b"
如果列表很长,我什至不知道列表中有多少种元素怎么办?
Python中有没有可以做到这一点的函数?或者,我该如何编写一个 for 循环来做到这一点?
【问题讨论】:
标签: python list python-2.7
只需使用sets:
x = [1,1,1,1,2,2,2,"a","a","a","b","b"]
uniques = set(x) # the magic!
print uniques # results: set(['a', 1, 2, 'b'])
当然,如果你想要一个列表对象(感谢@alfasin):
uniques = list(set(x))
通常编程语言将集合表示为一系列独特元素(尽管我可以看到在数学中这似乎不是规则)。
相关有用的链接:
【讨论】:
list(set(mylist)) ;)
如果您想保持元素在原始列表中出现的顺序,请使用itertools 库中的groupby:
>>> import itertools
>>> [k for k, v in itertools.groupby(x)]
[1, 2, 'a', 'b']
这假设相同的元素已经组合在一起,就像在您的列表中一样(想想 *nix 系统中的 uniq 实用程序)。
【讨论】:
groupby 需要对输入进行排序。
这应该可行:
x = [1,1,1,1,2,2,2,"a","a","a","b","b"]
l = []
for item in x:
if (item not in l):
l.append(item)
print(l)
【讨论】:
x 真的很长,那么会很慢。当然,如果它很短,在实践中就没有多大关系。
如何打印列表中的元素(不重复) x=[1,1,1,1,2,2,2,"a","a","a","b","b"]
您正在寻找的是获取列表的唯一元素 的函数。一般来说,你想要的是一个set,by definition 只包含独特的元素。
Python中有没有可以做到这一点的函数?或者,我该如何编写一个 for 循环来做到这一点?
Python 提供了几种方法来做到这一点,这取决于您的具体需求,其中一种更合适。以下是几个例子:
# order and selection don't matter
print set(x)
# preserve item order
print dict(zip(x, x)).keys()
# filter, order not preserved
print set(filter(lambda s : True if isinstance(s, str) else False, x))
# filter, preserve order
print (lambda x : [s for s in dict(zip(x,x)).keys() if isinstance(s, str)])(x)
如果列表很长,我什至不知道列表中有多少种元素怎么办?
理论上,如果您不知道列表中的内容,除了查看每个元素之外别无他法,如果您想确定的话。
如果您对列表有所了解,假设您知道每种至少有两个元素,并且按照您的示例中的顺序,您可以跳过一些元素并至少获得列表的近似值。
如果列表很大,这可能会很有趣(尽管我怀疑它有什么真正的区别,因为列表已经在内存中)。举个例子:
# c is the number of items that at least appear in sequence. here
# we only touch every other element, so we have reduced the number
# of accesses to x by n/2.
(lambda x, c : set(( x[i] for i in range(0, len(x), c) )))(x, 2)
=> {1, 2, 'a', 'b'}
【讨论】:
您可以使用for 循环:
x=[1,1,1,1,2,2,2,"a","a","a","b","b"]
non_repetitive = []
for item in x:
if item not in non_repetitive:
non_repetitive.append(item)
【讨论】:
是的,有一种简单的方法可以做到这一点,
x=[1,1,1,1,2,2,2,"a","a","a","b","b"]
print set(x)
但是,您也可以使用 for 循环和字典通过迭代列表并记录各种不同元素出现的频率来实现相同的输出。
dummy_dict = {}
for element in x:
if not element in dummy_dict:
dummy_dict[element] = 1
print dummy_dict.keys()
最好使用字典,因为从字典中访问值是在 O(1) 时间或恒定时间内完成的。
【讨论】:
collections.Counter。
如果打印时元素的顺序无关紧要,则使用集合。
>>> x=[1,1,1,1,2,2,2,"a","a","a","b","b"]
>>> list(set(x))
['a', 1, 2, 'b']
【讨论】:
set 正是这样做的,尽管它不保留它在输入列表中出现的顺序。如果您想保留此订单,请查看以下内容:
def nonRepeats(L):
answer = []
for e in L:
if e not in answer:
answer.append(e)
return answer
现在,这将返回非重复元素的列表,其顺序与它们在 L 中出现的顺序相同。
但请注意if e not in answer。该行检查e 是否在answer(这是一个列表)中。我们知道列表中的成员资格测试需要 O(n) 时间,即有必要测试列表中的几乎所有元素以确定该元素是否存在于列表中。这变得相当昂贵,因为在最坏的情况下,answer 可能会增长到L 的大小,使得该行在执行该函数时花费 O(n^2) 时间。
所以,我们可以让这个函数运行得更快一点(通过用一点空间成本来抵消时间成本):
def nonRepeats(L):
seen = set()
answer = []
for e in L:
if e not in seen:
answer.append(e)
return answer
由于seen 是set,成员资格测试只需花费O(1),这意味着if e not in seen 行花费函数O(n) 时间。
现在,进入太空:seen 集合可能会增长到L 的大小。这意味着您将不需要更多空间作为输入列表的大小来维护seen(因此,如果您尝试在某种内存有限的嵌入式系统中使用它,这可能是个坏主意)。
请注意,由于seen 是一个set,它是一个哈希表,因此此解决方案要求输入列表中的所有元素都是可哈希的,但情况并非总是如此(如果输入列表包含一个列表,这个解决方案在当前形式下变得不可用;但是,整数和字符串是可散列的,所以这应该适合您的用例)
【讨论】:
list(OrderedDict.fromkeys(seq))。
如果你只希望每个元素出现一次,例如:
输入:[2,2,1,1,3,3,3,1,1]
输出:[2,1,3]
用途:
from collections import OrderedDict
answer = OrderedDict(zip(x, xrange(len(x)))).keys()
但如果您希望输出为:[2,1,3,1],请使用 ajcr 的答案。
如果您不关心订单,请使用 felipsmartins 的回答。
说明:有序字典是字典,因此它们保持键的唯一性。它们也是有序的,所以键的顺序就是插入的顺序。
您实际上需要set,因为只有键,没有值,但没有 OrderedSet。所以zip被用来生成一个元组列表,然后这个列表作为(键,值)对的列表插入到OrderedDict中。 xrange(len(x)) 只是生成一个从 0 到 len(x) 的列表(实际上是一个 xrange 对象,但在这里不相关),但是您可以使用任何长度为 len(x) 的列表,因为您不在乎关于价值观。
【讨论】:
如果内存是一个问题,那么在填充另一个时清空一个。
your_list = [1,2,1,1,1,1,2,2,2,2,44,4,4,2,2,22,,6,6,5,5,5]
unique_set = set()
while your_list:
unique_set.add(your_list.pop())
【讨论】:
简单的列表推导在 O(n) 时间内工作的假设是,在具有相同值的两个元素之间不存在包含与这两个元素不同值的元素的元素子序列。
x=[1,1,1,1,2,2,2,"a","a","a","b","b"]
res = [x[i] for i in range(len(x)) if x[i] != x[i-1]]
#If all the elements of the list have the same value.
if len(res) == 0 and len(x) > 0:
res.append(x[0])
print res
出来:
[1, 2, 'a', 'b']
【讨论】: