Henry
Henry

Reputation: 23

How can I print the elements (non repetitive) in a list

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

Answers (11)

felipsmartins
felipsmartins

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

user4638556
user4638556

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

Rcynic
Rcynic

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

Alex Riley
Alex Riley

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

Ella Sharakanski
Ella Sharakanski

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

miraculixx
miraculixx

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

inspectorG4dget
inspectorG4dget

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

Subhasish
Subhasish

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

ZdaR
ZdaR

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

A.J. Uppal
A.J. Uppal

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

Lemagegris
Lemagegris

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

Related Questions