The code below seems to be iterating through a 2d list using another list which conceptually doesn't make much sense to me.
What would be the in range equivalent to the code below, using lens as I'm finding it quite difficult to understand.
I've changed the variable names as I'm working on coursework but if its too abstract I can add in the original variable names.
#list2 is a 2d list
#list1 is a normal list
for list1 in list2
for k in range(n) #n and k are constants
#any if statement
A "2D" list is just a list where each element is itself a list. To access each element of the lists inside the "main" list, do
for list1 in list2:
for element in list1:
print(element)
If you want a version using range:
L2 = len(list2)
for i in range(L2):
list1 = list2[i]
L1 = len(list1)
for j in range(L1):
element = list1[j]
print(element)
As should be clear from the above, using range in a for loop is very rarely a good idea, as the code is much less readable.
Related
I have 2 list of lists:
list1: [[1,2,3],[2,5],[6,7,4]]
list2: [[1,3],[2],[6,4],[9,0,3]]
I want to do few things:
Find every number that is in list 1 but is not in list 2, store it in a new list, and then append this new list to list2.
In our case: new_list = [5,7]
and then, we will add it to list2 = [[1,3],[2],[6,4],[9,0,3],[5,7]]
Then, I want to remove duplicates of numbers from each list1 and list 2:
In our case: list1 = [[1,3],[2,5],[6,7,4]], list2 = [[1],[2],[6,4],[9,0,3],[5,7]]
I have an implementation using For loops, but I need something more elegant for that.
Can you help me please find out a way?
Using Python, you can do the first part with a set comprehension:
list2.append(list({i for j in list1 for i in j}.difference({i for j in list2 for i in j})))
This is just a small part of my homework assignment. What im trying to do is iterate through list1 and iterate backwards through list2 and determine if list2 is a reversed version of list1. Both lists are equal length.
example: list1 = [1,2,3,4] and list2 = [4,3,2,1]. list2 is a reversed version of list1. You could also have list1 = [1,2,1] and list2 = [1,2,1] then they would be the same list and also reversed lists.
Im not asking for exact code, im just not sure how i would code this. Would i run 2 loops? Any tips are appreciated. Just looking for a basic structure/algorithm.
edit: we are not allowed to use any auxiliary lists etc.
You can just iterate backwards on the second list, and keep a counter of items from the start of the first list. If items match, break out of the loop, otherwise keep going.
Here's what it can look like:
def is_reversed(l1, l2):
first = 0
for i in range(len(l2)-1, -1, -1):
if l2[i] != l1[first]:
return False
first += 1
return True
Which Outputs:
>>> is_reversed([1,2,3,4], [4,3,2,1])
True
>>> is_reversed([1,2,3,4], [4,3,2,2])
False
Although it would be easier to just use builtin functions to do this shown in the comments.
The idea here is that whenever you have an element list1[i], you want to compare it to the element list2[-i-1]. As required, the following code creates no auxiliary list in the process.
list1 = [1, 2, 3]
list2 = [3, 2, 1]
are_reversed = True
for i in range(len(list1)):
if list1[i] != list2[-i - 1]:
are_reversed = False
break
I want to point out that the built-in range does not create a new list in Python3, but a range object instead. Although, if you really want to stay away from those as well you can modify the code to use a while-loop.
You can also make this more compact by taking advantage of the built-in function all. The following line instantiate an iterator, so this solution does not create an auxiliary list either.
are_reversed = all(list1[i] == list2[-i - 1] for i in range(len(list2))) # True
If you want to get the N'th value of each list you can do a for loop with
if (len(list1) <= len(list2):
for x in range(0, len(list1):
if (list1[x] == list2[x]):
#Do something
else:
for x in range(0, len(list2):
if (list1[x] == list2[x]):
#Do something
If you want to check if each value of a list with every value of another list you can nestle a for loop
for i in list1:
for j in list2:
if (list1[i] == list2[j]):
//Do something
EDIT: Changed code to Python
I am having a hard time trying to understand how the "for" function works.
I want to make a script that only outputs the strings in list2 that are not inside list1. For example:
list1 = ["link1.com", "link2.com", "link3.com"]
list2 = ["link2.com", "link123.com"]
for list2 in list1:
print(list2)
{My intention was that the code printed:
link123.com
But instead it printed the strings from list1}
I can't get it to work. Help would be much appreciated. I am using python 3 by the way.
Use Set for this .
set(list2)-set(list1)
Check with python set
The loop for list2 in list1 is actually an assignment: in each iteration the variable list2 gets the value of the next item in list1 - that is why only the elements of list1 are printed.
You could iterate over the elements of list2 and print, if they are not in list1:
for element in list2:
if element not in list1:
print(element)
Or if you want to use a for loop (note that this isn't very efficient for large lists):
for string in list2:
if not string in list1:
print (string)
For loops
For loops allow you to repeat a piece of code multiple times. You could easily just write a conditional and a print statement multiple times for each item in the list. A for loops allows you to write that piece of code once and have it repeated for each item in the list.
You can iterate over item in list2 by doing the following
for item in list2:
print(item)
item is an arbitrary variable name that holds the value of the current item we are on, what follows in is the list that we want to iterate over. print(item) is the piece of code we want to repeat for each element in the list.
What this does is goes through every item in list2 and prints them but that is not what we want. We want to check to make sure that item is not in list1. This can be achieved through a conditional statement.
if item not in list1:
print(item)
Now we can join the two piece of code together.
for item in list2:
if item not in list1:
print(item)
Sets
Are a collection of items in no order where every item is unique. These sets are the same ones we encounter in mathematics, therefore we can perform mathematical set operations on them.
To go from a list of items to a set we use sList1 = set(list1) sList1 is now of type set and stores the elements in list1. The same can be done for list2.
Now that we have sList1 and sList2 we want to eliminate any duplicates in the two for that we can take the difference of sList1 and sList2 and print them out as follows print(sList2-sList1).
We can do all of this in one step.
print( set(list2) - set(list1) )
The semantic, that python will check if these items are in list1 is NOT part of the for-each-loop.
The 'set' - solution is maybe too advanced for you.
So straightforward you would:
for item in list2:
if item not in list1:
print(item)
I've got a list in which some items shall be moved into a separate list (by a comparator function). Those elements are pure dicts. The question is how should I iterate over such list.
When iterating the simplest way, for element in mylist, then I don't know the index of the element. There's no .iteritems() methods for lists, which could be useful here. So I've tried to use for index in range(len(mylist)):, which [1] seems over-complicated as for python and [2] does not satisfy me, since range(len()) is calculated once in the beginning and if I remove an element from the list during iteration, I'll get IndexError: list index out of range.
Finally, my question is - how should I iterate over a python list, to be able to remove elements from the list (using a comparator function and put them in another list)?
You can use enumerate function and make a temporary copy of the list:
for i, value in enumerate(old_list[:]):
# i == index
# value == dictionary
# you can safely remove from old_list because we are iterating over copy
Creating a new list really isn't much of a problem compared to removing items from the old one. Similarly, iterating twice is a very minor performance hit, probably swamped by other factors. Unless you have a very good reason to do otherwise, backed by profiling your code, I'd recommend iterating twice and building two new lists:
from itertools import ifilter, ifilterfalse
l1 = list(ifilter(condition, l))
l2 = list(ifilterfalse(condition, l))
You can slice-assign the contents of one of the new lists into the original if you want:
l[:] = l1
If you're absolutely sure you want a 1-pass solution, and you're absolutely sure you want to modify the original list in place instead of creating a copy, the following avoids quadratic performance hits from popping from the middle of a list:
j = 0
l2 = []
for i in range(len(l)):
if condition(l[i]):
l[j] = l[i]
j += 1
else:
l2.append(l[i])
del l[j:]
We move each element of the list directly to its final position without wasting time shifting elements that don't really need to be shifted. We could use for item in l if we wanted, and it'd probably be a bit faster, but when the algorithm involves modifying the thing we're iterating over, I prefer the explicit index.
I prefer not to touch the original list and do as #Martol1ni, but one way to do it in place and not be affected by the removal of elements would be to iterate backwards:
for i in reversed(range(len()):
# do the filtering...
That will affect only the indices of elements that you have tested/removed already
Try the filter command, and you can override the original list with it too if you don't need it.
def cmp(i): #Comparator function returning a boolean for a given item
...
# mylist is the initial list
mylist = filter(cmp, mylist)
mylist is now a generator of suitable items. You can use list(mylist) if you need to use it more than once.
Haven't tried this yet but.. i'll give it a quick shot:
new_list = [old.pop(i) for i, x in reversed(list(enumerate(old))) if comparator(x)]
You can do this, might be one line too much though.
new_list1 = [x for x in old_list if your_comparator(x)]
new_list2 = [x for x in old_list if x not in new_list1]
Coming from R, this was hard to grasp. Taking elements from a list start with position 0.
The problem is that using one list to select items from another list are not running at the same pace here.
list1 = [1,2,3,4]
list2 = [1,2,3,4]
for x in range(0, len(list1)):
print(list1[list2[x]])
This will result in:
>> 2
>> 3
>> 4
>> IndexError: list index out of range
When I put an extra item in the start of list1, and added an item at the end of list2, the problem stops (simply because they are not synchronous like this).
Obviously I am not familiar with the language yet, what would be the correct way to use values from one list to select values from another?
Is this the correct way to think of it?
for x in range(0, len(list1)):
print(list1[list2[x]-1])
Python is 0-index based. seq[0] is the first element in seq.
R is 1-index based.
So, yes, in python you could use
list1 = [1,2,3,4]
list2 = [1,2,3,4]
for x in range(0, len(list2)):
print(list1[list2[x]-1])
The range should go up to len(list2), not len(list1).
Also, range(0, len(list2)) is the same as range(len(list2)). When
range is passed only one argument, it is interpreted as the stop
value, with a start value of 0 taken by default.
Note that in Python
for x in range(...):
can often be avoided, and if so, is preferable. Instead, you can write
for item in list2:
print(list1[item-1])
and item will be assigned to each of the items in list2.
If your list has 4 items, your indexes must run from 0 to 3, so using the value 4 throws an error. Here's an example with letters which might make it clearer:
list1 = [0,2,1,3]
list2 = ['a','a','d','m']
for x in list1:
print(list2[x]),
=> a d a m