Python looping through multiple lists - python

I've this code:
for i in range(0, len(codiceCassExcel)):
count1step += 1
for j in range(0, len(vwLinesToList)):
if data_reg[i] == vwLinesToList[j][1]:
if codiceCassExcel[i] == vwLinesToList[j][0]:
#Gestione movimento diverso da 601 e non bolle nostre
if tipo_mov[i] != 601 and len(vwLinesToList[j][7]) != 8:
count2step += 1
if ((int(qta_movimentata[i]) + int(vwLinesToList[j][4])) != 0) or ((int(-qta_movimentata[i]) + int(vwLinesToList[j][3])) != 0):
imballoColumnIn.append(vwLinesToList[j][0]),
dateColumnIn.append(vwLinesToList[j][1]),
absColumnIn.append(vwLinesToList[j][2]),
inColumnIn.append(vwLinesToList[j][3]),
outColumnIn.append(vwLinesToList[j][4]),
ddtColumnIn.append(vwLinesToList[j][7]),
wkColumnIn.append(vwLinesToList[j][8])
elif vwLinesToList[j][7] == bolla_excel[i]:
if ((int(qta_movimentata[i]) + int(vwLinesToList[j][4])) != 0) or (
(int(-qta_movimentata[i]) + int(vwLinesToList[j][3])) != 0):
imballoColumn.append(vwLinesToList[j][0]),
dateColumn.append(vwLinesToList[j][1]),
absColumn.append(vwLinesToList[j][2]),
inColumn.append(vwLinesToList[j][3]),
outColumn.append(vwLinesToList[j][4]),
ddtColumn.append(vwLinesToList[j][7]),
wkColumn.append(vwLinesToList[j][8])
I've 5 lists with hundred of items and a lists with similar items (vwLinesToLists). I want to check if:
firstListItem[i] and secondListItem[i](and so on...) is equal to
vwLinesToList[j][1], vwLinesToList[j][2], vwLinesToList[j][3]
If it's true, check if nListItem - vwLinesToList[j][6] != 0:
append each vwLinesToList[item] to separate list
I need an hint about write my code without all this nested stuff.
Thank you in advance

Use zip method to iterate over your lists. See zip lists in python for code samples.
Also consider using of izip_longest function which may be useful to...

Related

comparing each sequence created in the loop to the previous

I have created a function in python which randomly generates nucleotide sequence:
import random
selection60 = {"A":20, "T":20, "G":30, "C":30}
sseq60=[]
for k in selection60:
sseq60 = sseq60 + [k] * int(selection60[k])
random.shuffle(sseq60)
for i in range(100):
random.shuffle(sseq60)
def generateSequence(self, length):
length = int(length)
sequence = ""
while len(sequence) < length:
sequence="".join(random.sample(self, length))
return sequence[:length]
Now, I would like to check that while I apply this function, if a newly created sequence has a similarity of > 10% to the previous sequences, the sequence is eliminated and a new one is created:
I wrote something like this:
lst60=[]
newSeq=[]
for i in range(5):
while max_identity < 10:
newSeq=generateSequence(sseq60,100)
identity[i] = [newSeq[i] == newSeq[i] for i in range(len(newSeq[i]))]
max_identity[I]=100*sum(identity[i]/length(identity[i])
lst60.append(newSeq)
print(len(lst60))
However, it seems I get an empty list
You have to use a nested for loop if you want to compare ith sequence with jth sequence for all 1 <= j < i.
Further, I created a separate getSimilarity function for easier code readability. Pass it an old and new sequence to get the similarity.
def getSimilarity(old_seq, new_seq):
similarity = [old_seq[i] == new_seq[i] for i in range(len(new_seq))]
return 100*sum(similarity)/len(similarity)
lst60=[generateSequence(sseq60,100)]
for i in range(1,5):
newSeq = ""
max_identity = 0
while True:
newSeq = generateSequence(sseq60,100)
for j in range(0,i):
max_identity = max(max_identity, getSimilarity(lst60[j], newSeq))
if max_identity < 10:
break
lst60.append(newSeq)
print(len(lst60))

Intersection of lists having comparing 3 elements at a time

I have tried creating two separate lists by the name of 'sample' and 'game'. These contain outcomes of 3 games, eg, (1,1,0) (0,1,0) shown as [1,1,0,0,1,0] in both of the lists. I am trying to find intersection between both the lists through my last loop which should compare 3 elements of one list with 3 elements of another list and then return the match by appending it to list 'intersection'.
Eg, sample has [1,1,0,0,1,0] and game has [1,0,1,1,1,0,1,1,0]. The intersection of both should give me [1,1,0] that is the first 3 elements of 'sample' and 3 elements from index 3 of 'game'.
However, I am facing an error of index out of range.
Also, (1,1,0) in one list might get compared with the same (1,1,0) in other list twice, if that other list has (1,1,0) 2 times, which should not happen in intersection.
import random
P1 = 1/2 # win 1st game
P2 = 2/3 # win game immediately after a win
P3 = 1/3 # win game immediately after a loss
A = [0,1] # 0 for losing a game and 1 for winning a game
N = 100
sample_points = []; G1=[]; G2=[]; G3=[]
for i in range(N):
Game1 = random.choice([0,1])
Game2 = random.choice([0,1])
Game3 = random.choice([0,1])
G1.append(Game1)
G2.append(Game2)
G3.append(Game3)
sample_points.extend([Game1, Game2, Game3])
sample = []; game=[];intersection=[]
i = 0
# creating two separate lists
while i < len(sample_points):
if sample_points[i] + sample_points[i+1] + sample_points[i+2] == 2:
n1 = sample_points[i] ; n2 = sample_points[i+1] ; n3 = sample_points[i+2]
sample.append(n1);sample.append(n2);sample.append(n3)
if sample_points[i] == 1:
q1 = sample_points[i] ; q2 = sample_points[i+1] ; q3 = sample_points[i+2]
game.append(q1);game.append(q2);game.append(q3)
i = i+3
i=0
j=0
while j < len(sample):
for i in range(len(game)):
for j in range(len(sample)):
if game[i] == sample[j] and game[i+1] == sample[j+1] and game[i+2] == sample[j+2]:
intersection.append(sample[j]);intersection.append(sample[j+1]);intersection.append(sample[j+2])
j = j+3
i=i+3
Let's look at this block of code
while j < len(sample):
for i in range(len(game)):
for j in range(len(sample)):
if game[i] == sample[j] and game[i+1] == sample[j+1] and game[i+2] == sample[j+2]:
intersection.append(sample[j]);intersection.append(sample[j+1]);intersection.append(sample[j+2])
j = j+3
i=i+3
Notice the you let i and j to run until the very end of the vector and yet you consider indices like i+1 and i+2.
I would use range to indicate the increment by 3 and also we can compare two lists rather than using multiple and statement. I have also tried to use extend. You might like to replace it with something like
for i in range(0, len(game)-3, 3):
for j in range(0, len(sample)-3, 3):
if game[i:i+3] == sample[j:j+3]:
intersection.extend(sample[j:j+3])
print(intersection)
Also, you mentioned that you want to avoid duplicate, you might want to use set to check for duplicate for the two separate lists and then convert them back to a list.

Make my Nested loops Works simpler (Operating Time is Higher)

I am a learner in nested loops in python.
Below I have written my code. I want to make my code simpler, since when I run the code it takes so much time to produce the result.
I have a list which contains 1000 values:
Brake_index_values = [ 44990678, 44990679, 44990680, 44990681, 44990682, 44990683,
44997076, 44990684, 44997077, 44990685,
...
44960673, 8195083, 8979525, 100107546, 11089058, 43040161,
43059162, 100100533, 10180192, 10036189]
I am storing the element no 1 in another list
original_top_brake_index = [Brake_index_values[0]]
I created a temporary list called temp and a numpy array for iteration through Loop:
temp =[]
arr = np.arange(0,1000,1)
Loop operation:
for i in range(1, len(Brake_index_values)):
if top_15_brake <= 15:
a1 = Brake_index_values[i]
#a2 = Brake_index_values[j]
a3 = arr[:i]
for j in a3:
a2 = range(Brake_index_values[j] - 30000, Brake_index_values[j] + 30000)
if a1 in a2:
pass
else:
temp.append(a1)
if len(temp)== len(a3):
original_top_brake_index.append(a1)
top_15_brake += 1
del temp[:]
else:
del temp[:]
continue
I am comparing the Brake_index_values[1] element available between the range of 30000 before and after Brake_index_values[0] element, that is `range(Brake_index_values[0]-30000, Brake_index_values[0]+30000).
If the Brake_index_values[1] available between the range, I should ignore that element and go for the next element Brake_index_values[2] and follow the same process as before for Brake_index_values[0] & Brake_index_values[1]
If it is available, store the Value, in original_top_brake_index thorough append operation.
In other words :
(Lets take 3 values a,b & c. I am checking whether the value b is in range between (a-30000 to a+30000). Possibility 1: If b is in between (a-30000 to a+30000) , neglect that element (Here I am storing inside a temporary list). Then the same process continues with c (next element) Possibility 2: If b is not in b/w those range put b in another list called original_top_brake_index
(this another list is the actual result what i needed)
The result I get:
It is working, but it takes so much time to complete the operation and sometimes it shows MemoryError.
I just want my code to work simpler and efficient with simple operations.
Try this code (with numpy):
import numpy as np
original_top_brake_index = [Brake_index_values[0]]
top_15_brake = 0
Brake_index_values = np.array(Brake_index_values)
for i, a1 in enumerate(Brake_index_values[0:]):
if top_15_brake > 15:
break
m = (Brake_index_values[:i] - a1)
if np.logical_or(m > 30000, m < - 30000).all():
original_top_brake_index.append(a1)
top_15_brake += 1
Note: you can probably make it even more efficient, but this already should reduce the number of operations significantly (and doesn't change much the logic of your original code)
We can use the bisect module to shorten the elements we actually have to lookup by finding the smallest element that's greater or less than the current value. We will use recipes from here
Let's look at this example:
from bisect import bisect_left, bisect_right
def find_lt(a, x):
'Find rightmost value less than x'
i = bisect_left(a, x)
if i:
return a[i-1]
return
def find_gt(a, x):
'Find leftmost value greater than x'
i = bisect_right(a, x)
if i != len(a):
return a[i]
return
vals = [44990678, 44990679, 44990680, 44990681, 44990682, 589548954, 493459734, 3948305434, 34939349534]
vals.sort() # we have to sort the values for bisect to work
passed = []
originals = []
for val in vals:
passed.append(val)
l = find_lt(passed, val)
m = find_gt(passed, val)
cond1 = (l and l + 30000 >= val)
cond2 = (m and m - 30000 <= val)
if not l and not m:
originals.append(val)
continue
elif cond1 or cond2:
continue
else:
originals.append(val)
Which gives us:
print(originals)
[44990678, 493459734, 589548954, 3948305434, 34939349534]
There might be another, more mathematical way to do this, but this should at least simplify your code.

How to cycle through the index of an array?

line 14 is where my main problem is.i need to cycle through each item in the array and use it's index to determine whether or not it is a multiple of four so i can create proper spacing for binary numbers.
def decimalToBinary(hu):
bits = []
h = []
while hu > 0:
kla = hu%2
bits.append(kla)
hu = int(hu/2)
for i in reversed(bits):
h.append(i)
if len(h) <= 4:
print (''.join(map(str,h)))
else:
for j in range(len(h)):
h.index(1) = h.index(1)+1
if h.index % 4 != 0:
print (''.join(map(str,h)))
elif h.index % 4 == 0:
print (' '.join(map(str,h)))
decimalToBinary( 23 )
If what you're looking for is the index of the list from range(len(h)) in the for loop, then you can change that line to for idx,j in enumerate(range(len(h))): where idx is the index of the range.
This line h.index(1) = h.index(1)+1 is incorrect. Modified your function, so at least it executes and generates an output, but whether it is correct, i dont know. Anyway, hope it helps:
def decimalToBinary(hu):
bits = []
h = []
while hu > 0:
kla = hu%2
bits.append(kla)
hu = int(hu/2)
for i in reversed(bits):
h.append(i)
if len(h) <= 4:
print (''.join(map(str,h)))
else:
for j in range(len(h)):
h_index = h.index(1)+1 # use h_index variable instead of h.index(1)
if h_index % 4 != 0:
print (''.join(map(str,h)))
elif h_index % 4 == 0:
print (' '.join(map(str,h)))
decimalToBinary( 23 )
# get binary version to check your result against.
print(bin(23))
This results:
#outout from decimalToBinary
10111
10111
10111
10111
10111
#output from bin(23)
0b10111
You're trying to join the bits to string and separate them every 4 bits. You could modify your code with Marcin's correction (by replacing the syntax error line and do some other improvements), but I suggest doing it more "Pythonically".
Here's my version:
def decimalToBinary(hu):
bits = []
while hu > 0:
kla = hu%2
bits.append(kla)
hu = int(hu/2)
h = [''.join(map(str, bits[i:i+4])) for i in range(0,len(bits),4)]
bu = ' '.join(h)
print bu[::-1]
Explanation for the h assignment line:
range(0,len(bits),4): a list from 0 to length of bits with step = 4, eg. [0, 4, 8, ...]
[bits[i:i+4] for i in [0, 4, 8]: a list of lists whose element is every four elements from bits
eg. [ [1,0,1,0], [0,1,0,1] ...]
[''.join(map(str, bits[i:i+4])) for i in range(0,len(bits),4)]: convert the inner list to string
bu[::-1]: reverse the string
If you are learning Python, it's good to do your way. As #roippi pointed out,
for index, value in enumerate(h):
will give you access to both index and value of member of h in each loop.
To group 4 digits, I would do like this:
def decimalToBinary(num):
binary = str(bin(num))[2:][::-1]
index = 0
spaced = ''
while index + 4 < len(binary):
spaced += binary[index:index+4]+' '
index += 4
else:
spaced += binary[index:]
return spaced[::-1]
print decimalToBinary(23)
The result is:
1 0111

No errors, just doesn't print or do anything

I am pretty a beginner and I'm looking for help. I am supposed to write a simple programm which reads numbers from a file (they are ordered in two columns like this:
3 788506
255 879405
3 687899
255 697879 etc)
and always pairwise subtracts the number near 255 from the number near 3. The differences should be appended to a list. I also have to check whether the pair is rigt (e.g. that it's always 3 and 255 one after the other and not two 255s). So far I think I'm ready, but it doesn't do anything. I spent hours looking for my mistake, but I just cannot see what went wrong. I would appreciate any help.
filepath = "C:/liz/RT1-1.dat"
f = open (filepath, 'rU')
reac3 = []
reac255 = []
right_list = []
wrong_list = []
very_wrong_list =[]
li = [i.strip().split() for i in f.readlines()]
for element in li:
if int(element[0]) == 3: reac3.append(element[-1])
elif int(element[0]) == 255: reac255.append(element[-1])
k = 0
for i in range (0, len(li)+1, 2): #0,2,4,6,8 etc
if li[i][0] == 3 and li[i+1][0] == 255:
difference = int(reac255[k]) - int(reac3[k])
print int(difference)
k+=1
if difference > 300 and difference < 1200: right_list.append(difference)
else: wrong_list.append(difference)
else: very_wrong_list.append(li[i])
print right_list
i.strip().split() will return 2 strings .. therefore your comparison li[i][0] == 3 & li[i+1][0] == 5 should fail as li[i][0] & li[i+1][0] are still strings.
Also notice, that since len(li) should be even, then xrange(0, len(li) + 1, 2) will eventually make i = len(li) which should be out of the list boundaries.

Categories