Can a set have lists as its elements? [duplicate] - python

This question already has answers here:
Add list to set
(13 answers)
How to make a set of lists
(4 answers)
How to convert list of lists to a set in python so I can compare to other sets?
(3 answers)
Closed 5 years ago.
I am trying to get unique lists which can consist duplicate values,can I use sets to get unique lists?
To be more specific ,here is an example:
my_list=[[1,2,1],[1,2,2],[1,2,2],[1,1,2],[2,2,2]]
what i would want is :
set_list=[[1,2,1],[1,2,2],[1,1,2],[2,2,2]]
is this possible?
Thanks in advance for your kind response :)

No, a list is not hashable. You will get the following error:
TypeError: unhashable type: 'list'
Given the list only contains hashable objects, you can however convert the list to a tuple and add the tuples. So you could do something like:
>>> my_list=[[1,2,1],[1,2,2],[1,2,2],[1,1,2],[2,2,2]]
>>> set_tuples = {tuple(a_list) for a_list in my_list}
>>> set_tuples
{(1, 2, 2), (1, 2, 1), (2, 2, 2), (1, 1, 2)}
You can then for instance construct a uniqueness filter with:
my_list=[[1,2,1],[1,2,2],[1,2,2],[1,1,2],[2,2,2]]
result = []
unique_set = set()
for sublist in my_list:
the_tuple = tuple(sublist)
if the_tuple not in unique_set:
unique_set.add(the_tuple)
result.append(sublist)
So all operations on the set are done with tuples. This gives:
>>> result
[[1, 2, 1], [1, 2, 2], [1, 1, 2], [2, 2, 2]]

Lists are not hashable, but you can have a set of tuples, :
set(map(tuple, my_list))
# {(1, 1, 2), (1, 2, 1), (1, 2, 2), (2, 2, 2)}

Related

on the 'immutability' of tuples in python [duplicate]

This question already has answers here:
python tuple is immutable - so why can I add elements to it
(4 answers)
Closed 1 year ago.
If tuples are supposed to be immutable (which are in most cases), why can we change their data in the following way :
tuple = (1, 2, 3)
tuple += (4, 5)
print (tuple) #outputs (1, 2, 3, 4, 5)
You didn't mutate a tuple, you made a new one.
>>> tup = (1, 2, 3)
>>> tup2 = tup
>>> tup
(1, 2, 3)
>>> tup2
(1, 2, 3)
>>> tup += (4, 5)
>>> tup
(1, 2, 3, 4, 5)
>>> tup2
(1, 2, 3)
Initially, tup and tup2 refer to the same tuple. After the tup += (4, 5), tup refers to a new tuple and tup2 still refers to the old one. No mutation occurred.
Tuples are immutable which means you cannot update or change the values of tuple elements. You are able to take portions of existing tuples to create new tuples.
In your example, += sneakily stops being an in-place operator. tuple is a different tuple from when you started, because adding two tuples necessarily produces a new one, because tuples are immutable.

python reorder nested list from row to column [duplicate]

This question already has answers here:
Zip lists in Python
(10 answers)
Closed 2 years ago.
My input is
tbl_ports = [[1,2,3,4], [5,6,7,8], [9,10,11,12]]
And my expected output is
[[1,5,9], [2,6,10], [3,7,11], [4,8,12]]
My limit was to do the following to create the output reorder_list
reorder_list = []
for i in range(len(tbl_ports)):
for col in tbl_ports:
reorder_list.append(col[i])
reorder_list=[1, 5, 9, 2, 6, 10, 3, 7, 11]
How can I contain them in a list of 3 elements?
To fix the code that you already have, you need to create a new list every time a row is complete, such as:
reorder_list = []
for i in range(len(tbl_ports)):
reorder_list.append([])
for col in tbl_ports:
reorder_list[-1].append(col[i])
Which would yield the following result:
[[1, 5, 9], [2, 6, 10], [3, 7, 11]]
You can also use a more pythonic method of solving the problem,
list(zip(*tbl_port))
Which would yield a list of tuples:
[(1, 5, 9), (2, 6, 10), (3, 7, 11), (4, 8, 12)]
If you want a list of lists, then you can simply just use list comprehension:
[list(e) for e in zip(*tbl_port)]
Edit:
for an explanation of why zip(*list) works, you need to know what zip does.
zip is a function in python that takes in multiple lists, and outputs a generator of lists for each element in every corresponding list. So zip([1, 2, 3], [4, 5, 6]) would yield [(1, 4), (2, 5), (3, 6)].
the * basically expands the input into multiple positional arguments, where function(*[1, 2, 3, 4]) is equivalent to function(1, 2, 3, 4)
So the code passed in the input array as a list of arguments to the zip function, which then outputs the result in the order that you want.
The only remaining problem is that zip generates a generator instead of an actual list.
To solve that problem, simply call the list function on a generator to convert it into a list, or pass it in a list comprehension to yield the desired result.
This is exactly what the zip() function is for.
list(zip([1,2,3,4],'abcd'))
You can use the unpack syntax " * " to make python unpack your lists to the zip function.
tbl_ports = [[1,2,3,4], [5,6,7,8], [9,10,11,12]]
reorder_list = list(zip(*tbl_ports))

Understanding dictionary assignment with tuple and list

I am a python beginner and I recently learned about dictionary assignment.
Here's what I am attempting
my_list = [[1, 4], [2, 2],[5,1]]
lists = dict(my_list)
print(lists) # Prints {1:4,2:2,5:1}
my_list = [(1, 4), (2, 2),(5,1)]
lists = dict(my_list)
print(lists) # Prints {1:4,2:2,5:1}
my_list = [[1, 4], (2, 2),{5,1}]
lists = dict(my_list)
print(lists) # Prints {1:5,2:2}
I am unable to explain why we are getting this weird answer in example 3.
Kindly help and explain.
{5, 1} is a set and, as such, inherently unordered. It is, somewhat depending on your Python implementation, unpredictably iterated as either 1->5 or 5->1. If you catch the first case, your dict instantiation is equivalent to:
lists = dict([(1, 4), (2, 2), (1, 5)])
or, even more verbose and obvious
lists = {}
lists[1] = 4
lists[2] = 2
lists[1] = 5 # overrides first binding of 1
Since there can be no duplicate keys in a dict, the last key binding for a repeated key "wins".

Extracting corresponding elements of sublist [duplicate]

This question already has answers here:
Transpose nested list in python
(4 answers)
Transpose list of lists
(14 answers)
Closed 5 years ago.
It should work like
input: list([[1,1,1],[2,2,2],[3,3,3]])
output: [[1,2,3], [1,2,3], [1,2,3]]
so far i have done this:
def list(m):
list2=[]
for i in range(0, len(m)):
list2.append([x[i] for x in m])
return(list2)
It's not working every time..
For example:
it's working for
input: list([[1,1,1],[2,2,2],[3,3,3]])
but not for
input: list([[1,3,5],[2,4,6]])
You would usually do that in Python using the zip function:
inp = list([[1,1,1],[2,2,2],[3,3,3]])
output = list(map(list, zip(*inp)))
print(output)
>>> [[1, 2, 3], [1, 2, 3], [1, 2, 3]]
The additional map call is to convert the elements returned by zip, that are tuples, into lists, but if you are okay with tuples you can just do:
inp = list([[1,1,1],[2,2,2],[3,3,3]])
output = list(zip(*inp))
print(output)
>>> [(1, 2, 3), (1, 2, 3), (1, 2, 3)]
Also, the outer list is only necessary in Python 3, where zip returns a generator, but not in Python 2.

How to zip lists in a list [duplicate]

This question already has answers here:
Expanding tuples into arguments
(5 answers)
Closed 6 months ago.
I want to zip the following list of lists:
>>> zip([[1,2], [3,4], [5,6]])
[[1,3,5], [2,4,6]]
This could be achieved with the current zip implementation only if the list is split into individual components:
>>> zip([1,2], [3,4], [5,6])
(1, 3, 5), (2, 4, 6)]
Can't figure out how to split the list and pass the individual elements to zip. A functional solution is preferred.
Try this:
>>> zip(*[[1,2], [3,4], [5,6]])
[(1, 3, 5), (2, 4, 6)]
See Unpacking Argument Lists:
The reverse situation occurs when the arguments are already in a list or tuple but need to be unpacked for a function call requiring separate positional arguments. For instance, the built-in range() function expects separate start and stop arguments. If they are not available separately, write the function call with the *-operator to unpack the arguments out of a list or tuple:
>>> range(3, 6) # normal call with separate arguments
[3, 4, 5]
>>> args = [3, 6]
>>> range(*args) # call with arguments unpacked from a list
[3, 4, 5]

Categories