Reputation: 23
For example : x=[1,1,1,1,2,2,2,"a","a","a","b","b"]
And I want to print : 1,2,"a","b"
And what if the case is that the list is pretty long and I don't even know how many kinds of elements in the list?
Are there any functions in Python that can do it? Or, how do I write a for loop to do it?
Upvotes: 1
Views: 2706
Reputation: 13549
Just use 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'])
Of course, if you want a list object (thanks @alfasin):
uniques = list(set(x))
Generally programming language represent sets as a sequence of unique elements (Although I could see that in mathematics this does not seem to be a rule).
Related useful links:
Upvotes: 8
Reputation:
Simple list comprehension works in time O(n) under assumption, that between two elements with the same value there is no subsequence of elements which includes element of different value than those two elements.
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
out:
[1, 2, 'a', 'b']
Upvotes: 1
Reputation: 392
If memory is a concern then empty one as you fill the other.
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())
Upvotes: 1
Reputation: 176770
If you want to keep the order of the elements as they appear in the original list, use groupby
from the itertools
library:
>>> import itertools
>>> [k for k, v in itertools.groupby(x)]
[1, 2, 'a', 'b']
This assumes that equal elements are already grouped together, as in your list (think of the uniq
utility from *nix systems).
Upvotes: 5
Reputation: 2773
If you only want each element to appear once, for example:
Input: [2,2,1,1,3,3,3,1,1]
Output: [2,1,3]
Use:
from collections import OrderedDict
answer = OrderedDict(zip(x, xrange(len(x)))).keys()
But if you want the output to be: [2,1,3,1]
use ajcr's answer.
And if you don't care about the order use felipsmartins's answer.
Explanation: Ordered dicts are dictionaries, so they keep the keys unique. They are also ordered, so the order of keys are the order of insertion.
You actually need a set
since there are only keys, no values, but there is no OrderedSet. So zip
is used to generate a list of tuples, and then this list is inserted to the OrderedDict as a list of (key, value) pairs. xrange(len(x))
just generates a list (an xrange object, actually, but it isn't relevant here) from 0
to len(x)
but you could use any list with length of len(x)
instead, since you don't care about the values.
Upvotes: 1
Reputation: 10349
How can I print the elements (non repetitive) in a list x=[1,1,1,1,2,2,2,"a","a","a","b","b"]
what you are looking for is a function to get the unique elements of a list. In general what you want is a set
, which by definition only contains unique elements.
Are there any functions in Python that can do it? Or, how do I write a for loop to do it?
Python offers several ways to do this, depending on your specific needs one or the other is more appropriate. Here are a few examples:
# 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)
what if the case is that the list is pretty long and I don't even know how many kinds of elements in the list?
Theoretically, if you don't know what is in the list, there is no way other than to look at each element, if you want to be sure.
If you have some knowledge about the list, say you know there is at least two elements of each kind, and in sequence as in your example, you can skip a few elements and get at least an approximation of your list.
This could be interesting if the list is huge (although I doubt it makes any real difference, because the list is already in memory). As an example:
# 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'}
Upvotes: 1
Reputation: 113945
set
does exactly this, though it doesn't preserve the order in which it was presented in the input list. If you would like to preserve this order, take a look at this:
def nonRepeats(L):
answer = []
for e in L:
if e not in answer:
answer.append(e)
return answer
Now, this returns a list of non-repeating elements, in the same order in which they appeared in L
.
But take note of the if e not in answer
. That line checks whether e
is in answer
(which is a list). We know that membership testing in a list takes O(n) time, i.e. it is necessary to test pretty much all the elements in the list in order to determine whether the element exists in the list. This gets pretty expensive, as in the worst case, answer
could grow to be the size of L
, making that line cost O(n^2) time in the execution of that function.
So, we could make this function run a little faster (by offsetting the time cost with a little space cost):
def nonRepeats(L):
seen = set()
answer = []
for e in L:
if e not in seen:
answer.append(e)
return answer
Since seen
is a set
, membership testing only costs O(1), which means that the if e not in seen
line costs the function O(n) time.
Now, onto space: that seen
set could potentially grow to the size of L
. This means that you will need no more space as the size of your input list to maintain seen
(so this is probably a bad idea if you're trying to use this in some sort of embedded system with limited memory).
Note that since seen
is a set
, which is a hash table, this solution requires that all the elements in the input list are hashable, which isn't always the case (if the input list contains a list, this solution becomes unusable in its current form; but, integers and strings are hashable, so this should be fine for your use case)
Upvotes: 1
Reputation: 43
If the order of the elements does not matter when you print them, then use sets.
>>> x=[1,1,1,1,2,2,2,"a","a","a","b","b"]
>>> list(set(x))
['a', 1, 2, 'b']
Upvotes: 1
Reputation: 22954
Yes there is an easy way of doing this ,
x=[1,1,1,1,2,2,2,"a","a","a","b","b"]
print set(x)
However you can also use a for loop and a dictionary to achieve the same output by iterating over the list and recording the frequency of various distinct elements present.
dummy_dict = {}
for element in x:
if not element in dummy_dict:
dummy_dict[element] = 1
print dummy_dict.keys()
using dictionary is preferable since accessing the values from a dict is done in O(1) time , or constant time.
Upvotes: 1
Reputation: 19264
You can use a for
loop:
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)
Upvotes: 1
Reputation: 123
This should work :
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)
Upvotes: 2