Converting a set into list

P

Peter Otten

TheSaint said:
I've stumble to find a solution to get a list from a set

aa= ['a','b','c','f']
aa ['a', 'b', 'c', 'f']
set(aa)

To clarify: this creates a new object, so aa is still a list.
{'a', 'c', 'b', 'f'}
['a', 'b', 'c', 'f']

So you are actually converting a list to a (new) list here. Of course it
would have worked with a set or an arbitrary iterable, too.
</code>
I repute the comprehension list too expensive, is there another method?

mylist = list(myset)

Do you notice the similarity to converting a list to a set?
 
T

TheSaint

Peter said:
mylist = list(myset)
Do you notice the similarity to converting a list to a set?
There was something confusing me yesterday in doing that, but (for me
strangely) I got cleared out.

The point was that after a result from:

newset= set(myset1) & set(myset2)
list= [newset]

<< [{'bla', 'alb', 'lab'}]

Probably list(set) is not like [set].
 
T

TheSaint

Ben said:
Another method to do what?
Sorry, some time we expect to have said it as we thought it.

The example was to show that after having made a set

set(aa)

the need to get that set converted into a list.
My knowledge drove me to use a comprehension list as a converter.
In another post I got to know the simplest way to state

list(aa)
Where aa is a set.
 
C

Chris Angelico

newset= set(myset1) & set(myset2)
list= [newset]

<< [{'bla', 'alb', 'lab'}]

Probably list(set) is not like [set].

list(set) creates a list out of the set. [set] creates a list with one
element, the set itself. It's not a copy of the set, it's another
reference to the same set; change one and you'll see the change in the
other.

Chris Angelico
 
C

Chris Torek

As pointed out: you already know how to create a set from an object;
creating a list from an object is very similar:

list(set(aa))

But why are you doing that? What are you trying to achieve?

I have no idea why someone *else* is doing that, but I have used
this very expression to unique-ize a list:
x = [3, 1, 4, 1, 5, 9, 2, 6]
x [3, 1, 4, 1, 5, 9, 2, 6]
list(set(x)) [1, 2, 3, 4, 5, 6, 9]

Of course, this trick only works if all the list elements are
hashable.

This might not be the best example since the result is sorted
"by accident", while other list(set(...)) results are not. Add
sorted() or .sort() if needed:
x = ['three', 'one', 'four', 'one', 'five']
x ['three', 'one', 'four', 'one', 'five']
list(set(x)) ['four', 'five', 'three', 'one']
sorted(list(set(x))) ['five', 'four', 'one', 'three']
 
S

SigmundV

I think the OP wants to find the intersection of two lists.
list(set(list1) & set(list2)) is indeed one way to achieve this. [i
for i in list1 if i in list2] is another one.

Sigmund

Ben Finney   said:
As pointed out: you already know how to create a set from an object;
creating a list from an object is very similar:
   list(set(aa))
But why are you doing that? What are you trying to achieve?

I have no idea why someone *else* is doing that, but I have used
this very expression to unique-ize a list:

    >>> x = [3, 1, 4, 1, 5, 9, 2, 6]
    >>> x
    [3, 1, 4, 1, 5, 9, 2, 6]
    >>> list(set(x))
    [1, 2, 3, 4, 5, 6, 9]
    >>>

Of course, this trick only works if all the list elements are
hashable.

This might not be the best example since the result is sorted
"by accident", while other list(set(...)) results are not.  Add
sorted() or .sort() if needed:

    >>> x = ['three', 'one', 'four', 'one', 'five']
    >>> x
    ['three', 'one', 'four', 'one', 'five']
    >>> list(set(x))
    ['four', 'five', 'three', 'one']
    >>> sorted(list(set(x)))
    ['five', 'four', 'one', 'three']
    >>>
 
T

TheSaint

SigmundV said:
I think the OP wants to find the intersection of two lists.
list(set(list1) & set(list2)) is indeed one way to achieve this. [i
for i in list1 if i in list2] is another one

Exactly. I was confused on that I wasn't able to have a list in return.
The set intersection is the smartest result better than a "for" loop or a
comprehension list.
Infact the operatin loops are compiled into python, therfore they are the
fastest.
 
S

Steven D'Aprano

Chris said:
x = ['three', 'one', 'four', 'one', 'five'] x
['three', 'one', 'four', 'one', 'five']
list(set(x))
['four', 'five', 'three', 'one']

Why one *"one"* has purged out?
Removing double occurences in a list?

Break the operation up into two steps instead of one:

x = ['three', 'one', 'four', 'one', 'five']
s = set(x)
print s set(['four', 'five', 'three', 'one'])
list(s)
['four', 'five', 'three', 'one']


Once an element is already in a set, adding it again is a null-op:

set([42])
 
R

Roy Smith

SigmundV said:
I think the OP wants to find the intersection of two lists.
list(set(list1) & set(list2)) is indeed one way to achieve this. [i
for i in list1 if i in list2] is another one.

Both ways work, but the first is O(n) and the second is O(n^2).

import time
n = 10000
list1 = range(n)
list2 = range(n)
t0 = time.time()
list(set(list1) & set(list2))
t1 = time.time()
print "list(set) method took %f seconds" % (t1 - t0)
t0 = time.time()
[i for i in list1 if i in list2]
t1 = time.time()
print "loop method took %f seconds" % (t1 - t0)


../intersect.py 100000
list(set) method took 0.004791 seconds
loop method took 1.437322 seconds
 
T

Thomas Rachel

Am 15.05.2011 17:56 schrieb TheSaint:
SigmundV said:
I think the OP wants to find the intersection of two lists.
list(set(list1)& set(list2)) is indeed one way to achieve this. [i
for i in list1 if i in list2] is another one

Exactly. I was confused on that I wasn't able to have a list in return.
The set intersection is the smartest result better than a "for" loop or a
comprehension list.

I'm not sure about if it is really the smartest way.

s=set(list2); [i for i in list1 if i in s]
is in the same order of magnitude as the set operation. Both solutions
seem to be equivalent in that concerns the number of needed loop runs,
but this two-step operation might require one less loop over list1.

The set&set solution, in contrary, might require one loop while
transforming to a set and another one for the & operation.

Infact the operatin loops are compiled into python, therfore they are the
fastest.

Which loops do you mean here?


Thomas
 
D

Daniel Kluev

Both solutions seem to be equivalent in that concerns the number of needed loop runs, but this two-step operation might require one less loop over list1.
The set&set solution, in contrary, might require one loop while transforming to a set and another one for the & operation.

python -m timeit -s "l1 = range(1, 10000); l2 = range(5000, 15000)"
"l3 = list(set(l1) & set(l2))"
100 loops, best of 3: 2.19 msec per loop

python -m timeit -s "l1 = range(1, 10000); l2 = range(5000, 15000)"
"s=set(l2); l3 = [i for i in l1 if i in s]"
100 loops, best of 3: 2.45 msec per loop

python -m timeit -s "l1 = range(1, 100000); l2 = range(50000, 150000)"
"l3 = list(set(l1) & set(l2))"
10 loops, best of 3: 28 msec per loop

python -m timeit -s "l1 = range(1, 100000); l2 = range(50000, 150000)"
"s=set(l2); l3 = [i for i in l1 if i in s]"
10 loops, best of 3: 28.1 msec per loop

So even with conversion back into list set&set is still marginally faster.
 
P

Peter Otten

Daniel said:
Both solutions seem to be equivalent in that concerns the number of
needed loop runs, but this two-step operation might require one less loop
over list1. The set&set solution, in contrary, might require one loop
while transforming to a set and another one for the & operation.

python -m timeit -s "l1 = range(1, 10000); l2 = range(5000, 15000)"
"l3 = list(set(l1) & set(l2))"
100 loops, best of 3: 2.19 msec per loop

python -m timeit -s "l1 = range(1, 10000); l2 = range(5000, 15000)"
"s=set(l2); l3 = [i for i in l1 if i in s]"
100 loops, best of 3: 2.45 msec per loop

python -m timeit -s "l1 = range(1, 100000); l2 = range(50000, 150000)"
"l3 = list(set(l1) & set(l2))"
10 loops, best of 3: 28 msec per loop

python -m timeit -s "l1 = range(1, 100000); l2 = range(50000, 150000)"
"s=set(l2); l3 = [i for i in l1 if i in s]"
10 loops, best of 3: 28.1 msec per loop

So even with conversion back into list set&set is still marginally faster.

If you are looking for speed, consider

s = set(l1)
s.intersection_update(l2)
l3 = list(s)

$ python -m timeit -s "l1 = range(1, 10000); l2 = range(5000, 15000)"
"list(set(l1) & set(l2))"
100 loops, best of 3: 4 msec per loop

$ python -m timeit -s "l1 = range(1, 10000); l2 = range(5000, 15000)" "s =
set(l1); s.intersection_update(l2); list(s)"
100 loops, best of 3: 1.99 msec per loop
 
T

TheSaint

Thomas said:
Which loops do you mean here?

list(set) has been proved to largely win against
list = []
for item in set:
list.append(item)
or [list.append(item) for item in set]
 
C

Chris Torek

Chris Torek said:
x = [3, 1, 4, 1, 5, 9, 2, 6]
list(set(x))
This might not be the best example since the result is sorted
"by accident", while other list(set(...)) results are not.

A minor change to your example makes it out of order even for integers:
x = [7, 8, 9, 1, 4, 1]
list(set(x))
[8, 9, 1, 4, 7]

or for that mattter:
list(set([3, 32, 4, 32, 5, 9, 2, 6]))
[32, 2, 3, 4, 5, 6, 9]

Yes, but then it is no longer "as easy as pi". :)
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
474,161
Messages
2,570,892
Members
47,428
Latest member
RosalieQui

Latest Threads

Top