Here is my code for comparing two lists and print the output as 1 in lis1 is matched at position 2 in list2 so on..Can you please let me know how i can use nested for loops and break and continue statements
.Also any feasible approach to do this solution
def Iter(l1,l2):
for i in range(len(l1)):
for j in range(len(l2)):
if l1[i]==l2[j]:
print("matched at %d position"%l2[j])
break
l1=[1,2,3,4,5]
l2=[3,4,1,2,5]
Iter(l1,l2)
If I understood your question correctly, you just need to find the position of each item in first list, in the second list.
you can just use one loop to iterate in your first list. for each element you can check if that element exist in the second loop and if so, report the index:
def Iter(l1,l2):
for i,x in enumerate(l1):
try:
print(f"position {i} in first list matched at position {l2.index(x)} in second list")
except ValueError:
continue
the "try" and "except" part is just to handle the error that will arise when you try to use l2.index() on an element that exists in l1 but not l2.
You can simply use one loop if both the arrays are of equal length.
def Iter(l1,l2):
for i in range(len(l1)):
if l1[i]==l2[i]:
print("matched at %d position"%l2[i])
l1=[1,2,3,4,5]
l2=[1,2,1,2,5]
Iter(l1,l2)
output:
matched at 1 position
matched at 2 position
matched at 5 position
Your approach is time-inefficient, it's quadratic time. You can do it in linear time if you allow for linear space. Create a mapping of elements in list2 to their indices:
# assuming unique elements, you can modify to use a lists of indices as values to handle
l1 = [1,2,3,4,5]
l2 = [3,4,1,2,5]
index_map = {val:i for i, val in enumerate(l2)}
for val in l1:
if val in l2:
print(f"Matched {val} at position {index_map[val]}")
Related
I need to keep track of how many times I remove an element from my list. I have something like list remove(an element).
I tried:
c=0
list remove(an element)
c+=1
You must introduce a for loop throughout the list and then use the counter c. and u must initialize c outside the loop and print c outside the loop, like:
c=0
for i in range(0,len(list)):
if element in list:
list.remove(element)
c+=1
print(c)
The difference between the list length before the removal and after will tell you how many you removed.
pre_len = len(list)
list = [x for x in list if x != needle]
num_removed = pre_len - len(list)
I have two lists and need to compare and calculate element by element. As these lists get larger, performance is suffering. Someone recommended breaking one of the lists into N sections and running the comparison in parallel. How do I run these in parallel?
key={}
#compare each list, element by element
for i in range(len(list1)):
for j in range(len(list2)):
matched = False
try:
matched = match_function(list[i]['typeforma'], list[i]['typeformb'],list[j]['typeforma'], list[j]['typeformb'], )
except:
print("Error",i,j)
if matched:
# store two matches in the dictionary
key[list2[j]['id']]=list1[i]['identifier']
break;
j+=1
i+=1
Assuming you actually do need to compare the cartesian product (every element in list1 against every element in list2, as opposed to just comparing each element in list1 with the corresponding element in list2), the easiest way is to just replace your outer loop with a map call to a ProcessPoolExecutor or a Pool.
The only trick is that you don't want to try to share that mutable key dict; instead, pass back the individual dicts and merge at the end.
For example:
def compare_to_list2(i):
key = {}
for j in range(len(list2)):
matched = False
try:
matched = match_function(list[i]['typeforma'], list[i]['typeformb'],list[j]['typeforma'], list[j]['typeformb'], )
except:
print("Error",i,j)
if matched:
# store two matches in the dictionary
key[list2[j]['id']]=list1[i]['identifier']
break;
j+=1
return key
with concurrent.futures.ProcessPoolExecutor as x:
key = {}
for result in x.map(compare_to_list2, range(len(list1)), chunksize=1024):
key.update(result)
Experiment with chunksize, but first, there are ways to improve on this. For just one example, you should really be iterating directly over list1 and list2, not over range(len(list1)) and range(len(list2))—and doing that won't just make things simpler, but also more efficient, especially with large chunksizes. In fact, it's often best to simplify first, and then optimize.
I wrote a python program to print odd permutations of digits 1...9.
list1=[1,2,3,4,5,6,7,8,9] #this is used to generate permutations in lexicographic order
l3=[] #list to store odd permutations
k=7 # initial value of k
l3.append(list1)
while k!=-1:
l=0
#find value of l
for x in range(len(list1)-1,k,-1):
if list1[x]>list1[k]:
l=x
break
#swap values
p=list1[k]
list1[k]=list1[l]
list1[l]=p
#reverse the list
c1=list1[0:k+1]
c2=list1[k+1:]
c2.reverse()
list1=c1+c2
#finiding odd ones and printing them and storing them in l3 list
if list1[8]%2!=0:
l3.append(list1)
print list1 #in next program I replace this line with a for loop to print items in l3 list
k=-1
#find next value of k
for x in range(len(list1)-2,-1,-1):
if list1[x]<list1[x+1]:
k=x
break
This program print the expected results. But when i add this code to end of it instead print line the results changed completely .
for x in l3:
print x
I think I had made some silly mistakes but I can't find any error. plz help me to debug it.(I used permutation generating algorithm in Wikipedia(use k,l variables as mentioned in it).)
This is a copy by reference problem. Just replace the two occurrences of:
l3.append(list1) # cpoy by reference
with:
l3.append(list1[:]) # copy by value
I have a list L of 4-length list
L = [[1,2,12,13],[2,3,13,14],...]
and two integers a and b which appear many times in the sublists. What I want is to find the index of the sublists in L which contain a AND b.
I wrote a little code
l=[]
for i in range(len(L)):
if L[i][0]==a or L[i][1]==a or L[i][2]==a or L[i][3]==a:
l.append([i] + L[i]) # I put the index in the first position.
# Now l is a list of 5-length lists.
# I do the same loop on that list.
r=[]
for i in range(len(l)):
if l[i][1]==b or l[i][2]==b or l[i][3]==b or l[i][4]==b:
r.append(i)
The index I am looking for are in the list r. However I am pretty sure there is another way to do it in Python since I barely know this language. Maybe if my variable L is something else than a list of lists it would be easier/faster, because I will call this procedure a lot in my main program. (len(L) is around 3000)
By the way I know that the number of index is between one and four included, so I could put some break but I don't know if it will be faster.
---------------- EDIT 1 ----------------
Change "a or b (or is inclusive)" to "a AND b" in the second sentence. I wrote a mistake about my goal.
You can do this:
r = [i for i,x in enumerate(L) if any(y in x for y in (a,b))]
enumerate will give you both indices and values in your list comprehension, and the any statement will tell you if either a or b are in x, which is a sublist in L
Try with
for index, item in enumerate(L):
if a in item or b in item:
r.append(index)
Use any() to test the sublists:
if any(a in subl for subl in L):
This tests each subl but exits the generator expression loop early if a match is found.
This does not, however, return the specific sublist that matched. You could use next() with a generator expression to find the first match:
matched = next((subl for subl in L if a in subl), None)
if matched is not None:
matched[1] += 1
where None is a default returned if the generator expression raises a StopIteration exception, or you can omit the default and use exception handling instead:
try:
matched = next(subl for subl in L if a in subl)
matched[1] += 1
except StopIteration:
pass # no match found
This kind of thing is what list comprehension is made for.
If you really want inclusive or -- then this is the list you want. In your code, currently, you've giving and.
result = [a_tuple for a_tuple in L if a in a_tuple or b in a_tuple]
I am stuck in making a loop that will eliminate the values(from the alist) that are below average.
Thanks for the help.
a=input("Enter a list of values separated by a coma : ")
alist=eval(a)
print("the list is : ",alist)
average = sum(alist)/len(alist)
print("the average is : ",average)
for i in alist:
if alist[i]<average:
alist.remove[i]
You are almost there. Instead of removing elements, select elements you want to retain instead:
alist = [a for a in alist if a>=average]
Your mistake here is that for i in alist: is iterating over list elements themselves, not indexes, so alist[i] is throwing an error (or returning nonsense).
For the "loop" you can use a filter and a lambda function.
above_average = list(filter(lambda x: x >= average, alist))
For the rest of your code, I suggest you clean it up to something which is safer (use of eval is very bad)
import ast
user_string = raw_input('input a list of numbers separated by a commas: ')
alist = list(ast.literal_eval(user_string)))
So, in all, I would write your code as something like this:
import ast
user_string = raw_input('input a list of numbers separated by a commas: ')
numbers = list(ast.literal_eval(user_string)))
average = sum(numbers)/len(numbers)
print('The numbers: {}'.format(numbers))
print('The average: {}'.format(average))
above_average = list(filter(lambda x: x >= average, numbers))
# now do what you want with the above_average numbers.
Other answers tell you how to do it. I'll tell you why it doesn't work:
You iterate over the list and, at the same time, modify it.
This leads to items being missed during the iteration.
Why?
Internally, the iteration works via an index to the list. So it is the same as doing
idx = 0
while True:
try:
i = alist[idx]
except IndexError:
break
idx += 1
if alist[i] < average:
alist.remove(i)
What happens if you are at the element #3, go to the next one and then remove #3? Right, the indexes of the remaining ones move down and you are pointing to the one which formerly was #5. The old #4 is skipped at this test.
(BTW, I don't know if you noticed, I have replaced your [] behind .remove with ().)
You are mixing two ways of iterating a list: By index, and by element. In your loop, i is not the index, but the element of the list itself, thus alist[i] won't work.
If you use the for x in somelist loop, then x is the element itself, not the index of the element. For iterating over the indices, you can use for i in range(len(somelist)), or you could use for i, x in enumerate(somelist) to loop over tuples of index and element.
Also note that removing elements from a list or other kinds of collections while you are looping them generally is a bad idea. Better create a copy of the list.
for x in list(alist): # creates a copy of alist
if x < average: # remember: x is the element itselt
alist.remove(x) # remove element x from list
But the way you do it (with eval of a comma-separated string of numbers), alist is a tuple, not a list, and thus has no remove method at all. Thus you either have to convert it to a list before (alist = list(eval(a)), or use one of the approaches given in the other answers, creating a new list using list comprehension or filter and retaining the "good" elements.
As a general principle for asking StackOverflow questions like this, you should always include example input and output -- show what happens, and what you expect to happen.
In this case, I believe there are two three problems with your code:
Edit: Third, but possibly most importantly, look at glglgl's answer. If you implement the two fixes I describe below, you'll still have one problem: your code won't necessarily remove all the items you want to remove, because it'll skip over some items.
First, you say alist[i], which grabs the element of alist at index i. But saying for i in alist makes i be successive elements in the list already. Example:
mylist = [1, 2, 4]
for i in mylist:
print(i)
Would give you the output:
1
2
4
If you instead said this (which is like what you wrote)
mylist = [1, 2, 4]
for i in mylist:
print(mylist[i])
It wouldn't work as you'd expect, because you'd get the element at index 1, the element at index 2, and then try to get the element at index 4, but that wouldn't exist. You'll get something like this:
2
4
IndexError: list index out of range
Second, your syntax for removing an element is wrong. You should use alist.remove(i) instead of alist.remove[i]. You want to call a function, so you use parentheses. The square brackets are for indexing and slicing.