How to index a list using for loops? - python

I have a list of words.
mylist = ["aus","ausser","bei","mit","noch","seit","von","zu"]
I want to turn each element in the list into a sublist and add to each a number so that each entry is indexed. So it should output
[[1, 'aus'], [2, 'ausser'], [3, 'bei'], [4, 'mit'], [5, 'noch'], [6, 'seit'], [7, 'von'], [8, 'zu']]
I know how to do such a thing with a while loop
mylist = ["aus","ausser","bei","mit","noch","seit","von","zu","aus","ausser","bei","mit","noch","seit","von","zu","aus","ausser","bei","mit","noch","seit","von","zu"]
mylist2
i=0
while i <= 10:
mylist2.append([i,mylist[i]])
i = i +1
print(mylist2)
But I want to use the following kind of structure with a for-loop:
mylist = ["aus","ausser","bei","mit","noch","seit","von","zu"]
outlist =[[1,word] for word in mylist]
print(outlist)
I'm not sure how to do that with a for-loop. Can someone explain how to do this?

If you want the inner parts to be lists then you can cast the enumerate result to a list inside a list comprehension:
>>> mylist = ["aus","ausser","bei","mit","noch","seit","von","zu"]
>>> [[idx, item] for idx, item in enumerate(mylist, 1)]
[[1, 'aus'],
[2, 'ausser'],
[3, 'bei'],
[4, 'mit'],
[5, 'noch'],
[6, 'seit'],
[7, 'von'],
[8, 'zu']]

Use enumerate
>>> mylist = ["aus","ausser","bei","mit","noch","seit","von","zu"]
>>> list(enumerate(mylist, 1))
[(1, 'aus'),
(2, 'ausser'),
(3, 'bei'),
(4, 'mit'),
(5, 'noch'),
(6, 'seit'),
(7, 'von'),
(8, 'zu')]
If you need a list of lists instead of tuples, you can do
list(map(list(enumerate(mylist, 1))))
or
[[number, word] for number, word in enumerate(mylist, 1)]

Use enumerate:
[list(element) for element in list(enumerate(mylist, 1))]

This is the method I think you are looking for.
list1 = ["aus","ausser","bei","mit","noch","seit","von","zu"]
list2 = []
for i in range(len(list1)):
list2 += [[i+1, list1[i]]]
print (list2)
Uses a for loop to go through each item in list 1 and the indexes in list 1 and the adds 1 to the index so that it doesn't start with 0.

Related

I tried converting the tuples in a list of tuples using range and code worked but when i tried the same using 'for i in list:' it is not working:

lst = [(8, 7), (9, 6), (4, 8), (3, 5), (9, 4)]
for i in range(len(lst)):
lst[i] = list(lst[i])
this is working fine.
for i in lst:
i = list(i)
but this is not working. I don't know why ? Can anyone please tell me the reason ?
The docs for Mutable Sequence Types such as list explain assignment of an object x to an item at index i within a sequence s as follows:
Operation: s[i] = x
Result: item i of s is replaced by x
This means that the line in your code reading lst[i] = list(lst[i]) will replace item i of lst with list(lst[i])), which is a newly created list containing the elements of the tuple referenced by lst[i].
In contrast, consider your code reading:
for i in lst:
i = list(i)
The for statement assigns the item at index 0 of lst to the variable i and executes the statement i = list(i), then on its next iteration assigns the item at index 1 of lst to i and again executes the statement i = list(i), and so forth until lst has been exhausted.
Note that:
the assignment to the variable i by the for loop causes i to be a reference to an item in lst
because every item in lst is originally a tuple, and because tuple is an immutable sequence type, there is no way to change the object referenced by i and hence no way to change lst using i
Interesting side note: If lst were a list of lists (instead of a list of tuples), then we would be able to modify an item of lst using i, for example as follows:
lst = [[8, 7], [9, 6], [4, 8], [3, 5], [9, 4]]
for i in lst:
i[:] = i + [0]
i.append(1)
print(lst)
# Output:
[[8, 7, 0, 1], [9, 6, 0, 1], [4, 8, 0, 1], [3, 5, 0, 1], [9, 4, 0, 1]]
list(i) creates a new object of type list from the tuple i
i = list(i) assigns that new object to the variable i, so that i is now a reference to the newly created list object; the object that i previously referenced, namely the tuple item in lst, remains intact as an item of lst.
In the second option you just assign list(i) to the name i, then do nothing with it until it is overwritten in the next loop.
An alternative:
lst[:] = list(map(list, lst))
print(lst)
output: [[8, 7], [9, 6], [4, 8], [3, 5], [9, 4]]
In your first code
for i in range(len(lst)):
lst[i] = list(lst[i])
lst[i] is a variable which directly point to the element in list. Hence, any change in it effects the list itself.
Whereas in your second code
for i in lst:
i = list(i)
i is a variable used in for loop and is not pointing to the list lst. Hence, any change to id doesn't affect the lst.
What you are doing in the first code is,lst[i] = list(lst[i]) putting the value of the converted list in the index of the list whereas in your second code you are just assigning that converted list to i
you can try this:
lst = [(8, 7), (9, 6), (4, 8), (3, 5), (9, 4)]
lst = [list(i) for i in lst]

Remove list if it's contained in another list within the same nested list Python

I have a nested list:
regions = [[1,2,3],[3,4],[1,3,4],[1,2,3,5]]
I want to remove every list in this nested list which is contained in another one, i.e., [3,4] contained in [1,3,4] and [1,2,3] contained in [1,2,3,5], so the result is:
result = [[1,3,4],[1,2,3,5]]
So far I'm doing:
regions_remove = []
for i,reg_i in enumerate(regions):
for j,reg_j in enumerate(regions):
if j != i and list(set(reg_i)-set(reg_j)) == []:
regions_remove.append(reg_i)
regions = [list(item) for item in set(tuple(row) for row in regions) -
set(tuple(row) for row in regions_remove)]
And I've got: regions = [[1, 2, 3, 5], [1, 3, 4]] and this is a solution, but I'd like to know what's the most pythonic solution?
(sorry for not posting my entire code before, I'm a new to this...
Here is a solution with list comprehension and all() function :
nested_list = [[1,2,3],[3,4],[1,3,4],[1,2,3,5],[2,5]]
result = list(nested_list) #makes a copy of the initial list
for l1 in nested_list: #list in nested_list
rest = list(result) #makes a copy of the current result list
rest.remove(l1) #the list l1 will be compared to every other list (so except itself)
for l2 in rest: #list to compare
if all([elt in l2 for elt in l1]): result.remove(l1)
#if all the elements of l1 are in l2 (then all() gives True), it is removed
returns:
[[1, 3, 4], [1, 2, 3, 5]]
Further help
all() built-in function: https://docs.python.org/2/library/functions.html#all
copy a list: https://docs.python.org/2/library/functions.html#func-list
list comprehension: https://www.pythonforbeginners.com/basics/list-comprehensions-in-python
I'm definitely overlooking a simpler route, but this approach works
list comprehension
from itertools import product
l = [[1,2,3],[3,4],[1,3,4],[1,2,3,5]]
bad = [i for i in l for j in l if i != j if tuple(i) in product(j, repeat = len(i))]
final = [i for i in l if i not in bad]
Expanded explanation
from itertools import product
l = [[1,2,3],[3,4],[1,3,4],[1,2,3,5]]
bad = []
for i in l:
for j in l:
if i != j:
if tuple(i) in product(j, repeat = len(i)):
bad.append(i)
final = [i for i in l if i not in bad]
print(final)
[[1, 3, 4], [1, 2, 3, 5]]

Python rule of for statement

I just began learning Python. So I am a beginner. I have a question about "for statement." I think I still don't know the rule of it.
Please see below.
example:
list1 = []
list2 = []
def forStatement():
for i in range(3):
for j in range(5, 7):
list2.append(j)
list1.append(list2)
return list1
The result I am looking for is;
[[5, 6], [5, 6], [5, 6]]
But when I run that code, it turns out like this.
[[5, 6, 5, 6, 5, 6], [5, 6, 5, 6, 5, 6], [5, 6, 5, 6, 5, 6]]
Can anyone help me? How can I get that result?
Thank you so much.
You are almost correct, the only problem with your code is that you keep adding elements to list2. Instead, you should create a new list every time:
list1 = []
for i in range(3):
list2 = []
for j in range(5, 7):
list2.append(j)
list1.append(list2)
You are appending in the loop, where you want to reset list2 each iteration of i
list1 = []
for i in range(3):
list2 = []
for j in range(5, 7):
list2.append(j)
list1.append(list2)
>>> print list1
[[5, 6], [5, 6], [5, 6]]
For your code, list1 is a container object which takes references to an object to which list2 is bound. (Usually, such a object is mentioned as list2 for brevity.) After the execution of the code, list1 finally contains three elements (i.e. references to list2) and list2 obviously contains triple (outer loop executed 3 times) consecutive 5, 6 (every execution of inner loop append 5 and 6 to list2).
The following code should be what you expect:
list1 = []
list2 = None
for i in range(3):
list2 = [] # To create a new empty list object and let it bound to the variable list2 every outer loop.
for j in range(5, 7):
list2.append(j)
list1.append(list2)
In this code, after the execution, list1 contains three elements that are distinct objects. But they were all bound to the variable list2 in the past.

Compare i vs other items in a Python list

Good Day, I've googled this question and have found similar answers but not what I am looking for. I am not sure what the problem is called so I that doesn't help me and I am looking for an elegant solution.
How do I loop over a list, item at a time, and compare it to all other items in a list. For example, if I had a list
l = [1,2,3,4]
Each loop of the out would yield something like
1 vs [2,3,4]
2 vs [1,3,4]
3 vs [1,2,4]
4 vs [1,2,3]
One solution I've been playing with involves duplicating the list every iteration, finding the index of the item, deleting it from the duplicate list and compare the two. This route seems less ideal as you have to create a new list on every iteration.
You can use itertools.combiations to create all combinations of the length 3 from your list and then use set.defference method to get the difference element between the l and the combinations. but note that you need to convert your main list to a set object :
>>> from itertools import combinations
>>> l = {1,2,3,4}
>>> [(l.difference(i).pop(),i) for i in combinations(l,3)]
[(4, (1, 2, 3)), (3, (1, 2, 4)), (2, (1, 3, 4)), (1, (2, 3, 4))]
A simple approach would be to use two loops:
arr = [1,2,3,4]
for i in arr:
comp = []
for j in arr:
if i != j:
comp.append(j)
print(comp)
I guess you could use list comprehension. While still creating a new list every iteration, you don't need to delete an item each time:
l = [1,2,3,4]
for i in l:
temp = [item for item in l if item != i]
print temp
[2, 3, 4]
[1, 3, 4]
[1, 2, 4]
[1, 2, 3]

python replace list values using a tuple

If I have a list:
my_list = [3,2,2,3,4,1,3,4]
and a tuple
my_tuple = (3,5)
What's the best way of replacing elements in my_list using the tuple:
result = [5,2,2,5,4,1,5,4]
e.g.
for item in my_list:
if(item == my_tuple[0]):
item = my_tuple[1]
More generally, I would have a list of lists, and a list of tuples, and I would like to apply each of the tuples to each of the lists within the list of lists.
The more natural data structure for my_tuple is a dictionary. Consider something like this and use the .get() method:
>>> my_lists = [[3,2,2,3,4,1,3,4], [1,2,3,4,5,6]]
>>> my_tuple_list = [(3,5), (6, 7)]
>>> my_dict = dict(my_tuple_list)
>>> my_dict
{3: 5, 6: 7}
>>> my_lists = [[my_dict.get(x,x) for x in somelist] for somelist in my_lists]
>>> my_lists
[[5, 2, 2, 5, 4, 1, 5, 4], [1, 2, 5, 4, 5, 7]]
Per #Wooble's comment, your code will work if you enumerate.
list_of_lists = [[3,2,2,3,4,1,3,4], [1,3,5,3,4,6,3]]
list_of_tuples = [(3,5), (1,9)]
def tup_replace(mylist, mytuple):
for i, item in enumerate(mylist):
if item == mytuple[0]:
mylist[i] = mytuple[1]
return mylist
then you can just nest that some more to work on a list of list and list of tuples.
for mylist in list_of_lists:
for mytuple in list_of_tuples:
mylist = tup_replace(mylist, mytuple)
print mylist
That said, the dictionary approach is probably better.
Using if item == my_tuple[0], ... in a general case sounds like you are making a switch statement that you want to apply to each item in your list. Use a dictionary instead if you can. (Why isn't there a switch or case statement in python?)
Convert your list of tuples to a lookup dictionary (python's switch statement):
replacements = dict(my_tuples) #thanks to #julio
Then for a single list, reproduce the list with a comprehension, but replace each value with the new value from replacements if it exists:
replaced_list = [replacements.get(original,original) for original in my_list]
I guess there is a more efficient way to do it, but that's for a single list with a list of tuples. You say you also need to do it for a list of lists? Just nest that?
Could you explain more about where you are getting this data and why you need to do it?
If you are trying to replace every 3 in your list with 5, this will do:
[x == my_tuple[0] and my_tuple[1] or x for x in my_list]
If you want to do this, with more than one "translational" tuple, then I really suggest to use a dictionary instead:
trans = {3: 5, 4: 6}
[trans.get(x,x) for x in my_list]
And in the more general case where you have more than one list:
ll = [[3, 2, 3, 4], [5, 4, 3, 4]]
trans = {3: 5, 4: 6}
for i in range(len(ll)):
ll[i] = [trans.get(x,x) for x in ll[i]]
Supposing that you want to replace every old list in ll with the new one.

Categories