How to use sequence unpacking with a sequence of variable length? - python

If I know the length of a list in advance, I can use sequence unpacking to assign variable the elements of the list thus:
my_list = [1,2,3]
x, y, z = my_list
If I don't know the length of the list in advance, how can I assign variables to the elements of the list using sequence unpacking? If for argument's sake I don't care how the variables are named, can I first get the length of the list and then unpack to this amount of arbitrarily-named variables?

Certainly not recommend but possible:
my_list = [1, 2, 3]
for counter, value in enumerate(my_list):
exec 'a{} = {}'.format(counter, value)
print a0, a1, a2
Output:
1 2 3
Or use Python 3:
>>> a, *rest = my_list
>>> a
1
>>> rest
[2, 3]

you can force the length of the list to unpacking to the size you want like this
>>> my_list=range(10)
>>> a,b,c = my_list[:3]
>>> a
0
>>> b
1
>>> c
2
>>> my_list
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
>>>
if they are less you get a error, otherwise you take the 3 first elements
to the case of less elements you can do something like this
>>> my_list=[1,2]
>>> x,y,z=(my_list[:3] +[-1]*3)[:3]
>>> x
1
>>> y
2
>>> z
-1
>>>
have a list with default values that you concatenate to the sub-list of my_list and from the result you take what you need

The right answer is that you should leave these elements in a list. This is what a list is for.
The wrong answer is to add local variables in a roundabout way. For Python 3:
ctr = 0
for value in my_list:
__builtins__.locals()['my_list_{}'.format(ctr)] = value
ctr += 1
If my_list has n items, this will create variables my_list_0, my_list_1, ..., my_list_{n-1}.
Please don't do this.

Related

How to iterate the first index value twice before going to the next index position?

I'm trying to make a for loop that iterates each index twice before going to the next one, for example if I have the following list:
l = [1,2,3]
I would like to iterate it if it was in this way:
l = [1,1,2,2,3,3]
could someone help me with this problem please?
The most obvious thing would be a generator function that yields each item in the iterable twice:
def twice(arr):
for val in arr:
yield val
yield val
for x in twice([1, 2, 3]):
print(x)
If you need a list, then
l = list(twice([1, 2, 3]))
You could make a list comprehension that repeats the elements and flattens the result:
l = [1,2,3]
repeat = 2
[n for i in l for n in [i]*repeat]
# [1, 1, 2, 2, 3, 3]
You can solve this by using NumPy.
import numpy as np
l = np.repeat([1,2,3],2)
Repeat repeats elements of an array the specified number of times. This also returns a NumPy array. This can be converted back to a list if you wish with list(l). However, NumPy arrays act similar to lists so most of the time you don't need to change anything.
Unsurprisingly, more-itertools has that:
>>> from more_itertools import repeat_each
>>> for x in repeat_each([1, 2, 3]):
... print(x)
...
1
1
2
2
3
3
(It also has an optional second parameter for telling it how often to repeat each. For example repeat_each([1, 2, 3], 5). Default is 2.)
l = [1, 2, 3]
lst = []
for x in l:
for i in range(2):
lst.append(x)
print(lst)
# [1, 1, 2, 2, 3, 3]

Lists, how to add multiple values at one time

i just wondered if there is a way to append at one time multiple values i.e.
defining an function with the parameter x, that will automaticly append the amount of elements definied by an x.
def Append(x):
L = []
L.append(x - Elements)
return L
Thanks in advance
Try this to append several similar values to an existing list:
>>> l = [1,2]
>>> l += [3]*2
>>> l
[1, 2, 3, 3]
.extend() list method works too
>>> l = [1,2]
>>> l.extend([3]*2)
>>> l
[1, 2, 3, 3]
i meant it to add an x-Amount of Elements, not an specific one but just for example: Append(20) -> Should add 20 new elements

Separating/accessing a triple tuple list like [[[x,y],z],p]?

I am trying to access variables stored in a triple tuple list in python and I am not sure how to do it. I would like to be able to go through the list in a for loop and get x,y,x, & p from each tuple. How would I do that?
MovesList = [ [[[1,2],3],1] , [[[2,5],3],1] , [[[1,3],0],2] ]
You can unpack tuples as you iterate over them:
Python 2:
>>> for ((x,y),z),p in MovesList:
... print x, y, z, p
Python 3:
>>> for ((x,y),z),p in MovesList:
... print(x,y,z,p)
Both of which result in:
1 2 3 1
2 5 3 1
1 3 0 2
same unpacking with list comprehension
In [202]: [[x,y,z,p] for ([[x,y],z],p) in MovesList]
Out[202]: [[1, 2, 3, 1], [2, 5, 3, 1], [1, 3, 0, 2]]
I also found you can unpack a list of tuples that doesn't have a finite space by putting it through a while loop like so:
Mylist = list()
MyOtherList = list()
//list is packed my tuples of four {(a,b,c,d),(a,b,c,d),(a,b,c,d),...}
While MyList[0] != Null:
var w = MyList[0][0]
var x = MyList[0][1]
var y = MyList[0][2]
var z = MyList[0][3]
MyList.Remove(w,x,y,z)
//do something with w,x,y,z based upon use
MyOtherList = getMoreListItems(w,x,y,z)
MyList.extend(MyOtherList)
This can be used when the list you would like to iterate through is full of tuples of all the same size

Python function not modifying the list passed to it

Why doesn't the function x modify the contents of the list that is passed to it?
How can I change the MWE so that x does modify the contents of the list that is passed to it?
>>> def x(mylist):
... mylist = [ x for x in mylist if x > 5 ]
...
>>> foo = [1,2,3,4,5,6,7,8,9,10]
>>> x(foo)
>>> print foo
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
The function doesn't modify x because it is reassigning the name mylist to a new value. The alternative to this would be surprising.
a = 1
b = a
b = 2
assert a == 1 # would you want a to be 2 here?
If you want to replace the contents you can do so with a slice assignment
def x(mylist):
mylist[:] = [ x for x in mylist if x > 5 ]
The assignment operator in python doesn't go into any method calls. It is the mechanism for name rebinding. However, you can implement the __setitem__ method (as list does), which is more or less the operator []=
With slice assignment you are calling __setitem__ with a slice argument that says "replace this slice of the list with ..." where ... is the right side of the =
As Ryan Haining explained, x is reassigning the list. It should, however, only modify the list items:
def x(mylist):
for i in reversed(mylist):
if not i > 5:
mylist.remove(i)
Note that you should traverse the list in reversed order.

Concatenate List Object Name with a Number and Retain the List Python

I'm using python 2.7 I'm trying to figure out a way to change the names of my lists automatically.
Let me explain i have multiple lists
list1 = [1, 2, 3, 4, 5]
list2 = [4, 5, 9, 3]
list3 = [8, 4, 3, 2, 1]
I would like to call the lists in a loop to determine which lists contain or do not contain a particular number.
My first thought was
x = "list" + str(i) # (where i iterates in the loop)
print x
However, using the above code only gave me the string "list1"(when i=1).
What I want is to be able to call the list that is named list1 and use the .count() operator to determine whether or not the number exists if it doesn't i want to call the next list until I'm out of lists(there will eventually be up to 30 lists).
Thanks,
Ryan
You shouldn't approach it like this. Put your lists in a container to iterate over them instead:
In [5]: for l in (list1, list2, list3):
...: print l.count(2)
...:
1
0
1
What you could do in a real-life use case is create a list of lists and fill it dynamically.
Then to get the first list that contains a given number, you could do:
In [6]: lists = [list1, list2, list3]
In [7]: next(l for l in lists if 9 in l)
Out[7]: [4, 5, 9, 3]
put the list in dict:
list1 = [1,2.4]
list2 = [2,5,6]
dlist = {1:list1,2:list2}
for k in dlist:
print dlist[k]

Categories