Editing Values in the List of Dictionaries in Python - python

I have a list of dictionaries in python. The Dictionary contains "sequenceId" that I need to update for all Dictionaries making sure that each sequenceId is even and non-repeatable.
To update the sequenceIds, I am using a for loop, but the behavior is not what I expect.
seqId = 0
for index in range(20):
FinalNodes[index]['sequenceId'] = seqId
seqId +=2
print(FinalNodes[7]['sequenceId'])
Expected Output:- 14
Observed Output:- 38
Here is the full code snipet
import json
import time
with open('test.json', "r") as json_file:
data = json.load(json_file)
numberofJobs = 10
NodesList = data['nodes']
nNodes = len(NodesList)
#Divide all node into first, main and last
MainNodes = NodesList[1:nNodes-1]
FirstNode = NodesList[0:1]
LastNode = NodesList[nNodes-1:nNodes]
#prepare final nodes
FinalNodes = FirstNode.copy()
for i in range(numberofJobs):
FinalNodes.extend(MainNodes)
FinalNodes.extend(LastNode)
print(FinalNodes[7]['sequenceId'])
seqId = 0
for index in range(0,20):
FinalNodes[index]['sequenceId'] = seqId
seqId +=2
print(FinalNodes[index]['sequenceId'],index)
print(FinalNodes[7]['sequenceId'])
Output Inside the Loop:-
0 0
2 1
4 2
6 3
8 4
10 5
12 6
14 7
16 8
18 9
20 10
22 11
24 12
26 13
28 14
30 15
32 16
34 17
36 18
38 19

Please check with your FinalNodes dictionary as I ran the same code and it works fine!
FinalNodes= []
for i in range(20):
FinalNodes.append({"sequenceId":0})
seqId = 0
for index in range(8):
FinalNodes[index]['sequenceId'] = seqId
seqId +=2
print(FinalNodes[7]['sequenceId']) #14

Related

For loop runs and perform task on only the first element of the the iterable but not the rest and returns the result of only the action on 1st element

The last for loop of the code seems to only run for the first element of the list and not the rest of the element
a = int(input())
setA = set(map(int, input().split()))
n = int(input())
com = [input() for alnum in range(n*2)]
nestcom = []
cmd = []
for i in com:
if com.index(i)%2 == 0:
nestcom.append([i, com[com.index(i)+1]])
else:
continue
for x in nestcom:
y, z = x[0].split(), set(map(int, x[1].split()))
cmd.append([y, z])
for u in cmd:
eval('setA.'+cmd[0][0][0]+'('+str(cmd[0][1])+')')
print(sum(setA))
These are the inputs
16
1 2 3 4 5 6 7 8 9 10 11 12 13 14 24 52
4
intersection_update 10
2 3 5 6 8 9 1 4 7 11
update 2
55 66
symmetric_difference_update 5
22 7 35 62 58
difference_update 7
11 22 35 55 58 62 66
I tried running code with python 3 and pypy 3 but same problem. I changed the eval() to exec() but problem still persist
here is your last loop:
for u in cmd:
eval('setA.'+cmd[0][0][0]+'('+str(cmd[0][1])+')')
You are using cmd in what you are doing within the loop, not u. That is, you aren't using each element in cmd, you are just using cmd a number of times.
You likely want to use u in the loop itself (like eval('setA.'+u[0]...)), or perhaps enumerate(cmd) to get each element and a counter and use the counter itself, like for i, u in enumerate(cmd): eval('setA.'+cmd[i][0][0]...)

Is there a way to revert changes made to an element in a list?

I recently got help with fixing a function that changes elements in a list when printing said list. However, my program demands me being able to revert whatever changes I've made to an element in the list. Judging from the code, this should be doable with what I have, but it seems I can't alter the list once it has been altered once. The affected code looks like this:
def seatingmap():
# The parameters of seating-plan
rows = 6
seats = 4
seat_rows = [i for i in range(1, rows * seats + 1)]
seat_rows = [seat_rows[i:i + seats] for i in range(0, len(seat_rows), seats)]
return seat_rows
def find_in2Dlist(lst, item):
for index, sublist in enumerate(lst):
try:
aname = sublist.index(item)
return [index, aname]
except:
continue
return None
def printList(mlist, chosenseat):
i = 0
temp = mlist.copy()
while i < len(chosenseat):
findseat = find_in2Dlist(mlist, chosenseat[i])
if findseat == None:
i += 1
else:
temp[findseat[0]][findseat[1]] = '*' + str(temp[findseat[0]][findseat[1]]) + '*'
i += 1
for idx, row in enumerate(temp):
if idx == len(temp) // 2:
print("{:^{}}".format('↓ TYST AVD ↓', (len(row) * 4) - 2))
if idx % 2 == 1:
row = row[::-1]
print(("{:<4}" * len(row)).format(*row))
list = seatingmap()
number = [2]
printList(list, number)
number = [2,4]
printList(list, number)
Edit
If I for example run the code above, it changes this:
1 2 3 4
8 7 6 5
9 10 11 12
↓ TYST AVD ↓
16 15 14 13
17 18 19 20
24 23 22 21
To this:
1 *2* 3 *4*
8 7 6 5
9 10 11 12
↓ TYST AVD ↓
16 15 14 13
17 18 19 20
24 23 22 21
Which is good. Although, now I want be able to change it back to let's say:
1 2 3 *4*
8 7 6 5
9 10 11 12
↓ TYST AVD ↓
16 15 14 13
17 18 19 20
24 23 22 21
By removing the "2" from "chosenseats". This is where I'm stuck, as when I attempt to do this, it prints out the same list as before the 2 was removed.Is there any way I can go about this issue?
It could be fixed by simply refreshing the list each time you call printList or copying the list contents not the list, I feel that is an incomplete answer.
As far as I can see the below achieves the same result with a lot less code. It could be shortened more using list comprehensions etc. but I'm focussing here on removing unnecessary functions rather than just reducing the number of lines of code.
def generate_seatmap(rows = 6, seats_per_row = 4):
seatmap = []
for row in range(0,rows):
start_of_row = row*seats_per_row+1
seatmap.append([seat for seat in range(start_of_row,start_of_row+seats_per_row)])
return seatmap
def print_seatmap(seatmap,chosenseats=[]):
for row in seatmap:
if seatmap.index(row)%2: #reverse odd numbered rows
row.reverse()
for seat in row:
#add asterisks for seats we have chosen
printable_seat = '*'+str(seat)+'*' if seat in chosenseats else str(seat)
#add fewer spaces the longer our seat label now is up to a max of 4
print(printable_seat, end = ' '*(4-len(printable_seat)))
print("")
print_seatmap(generate_seatmap(),[1,2,24,23])

Low speed of python using while ,for,if-else condition

Hi I have below code in python .
I am comparing multiple columns to 1 single data each time based on certain flag value presence. Here two such sets are shown. ST9 and ST1
I am using while loop,for and if-else condition. But it is taking almost 13 minutes to process. How can I increase the computation speed.
i=0
Reslt_9=[]
while i<len(xx):
for val in xx.ST9:
if val==4:
xz = xx[['SV1','SV2','SV3','SV4','SV5','SV6','SV7','SV8','SV9','SV10','SV11','SV12']].eq(xx['G9'], axis=0).assign(no = True)
i1 = xz.values.argmax(axis=1)
Reslt_9 = np.append(Reslt_9,xx['R9'][i] -xx[['PR1','PR2','PR3','PR4','PR5','PR6','PR7','PR8','PR9','PR10','PR11','PR12']].assign(no = np.nan).values[xx.index, i1][i])
elif val==2:
Reslt_9=np.append(Reslt_9,0)
i=i+1
a2=0
Reslt_1=[]
aa=read_data
while a2<len(aa):
# Debug area
for val1 in aa.ST1:
if val1==4:
a = aa[['SV1','SV2','SV3','SV4','SV5','SV6','SV7','SV8','SV9','SV10','SV11','SV12']].eq(aa['G1'], axis=0).assign(no = True)
a1 = a.values.argmax(axis=1)
Reslt_1 = np.append(Reslt_1,aa['R1'][a2] - aa[['PR1','PR2','PR3','PR4','PR5','PR6','PR7','PR8','PR9','PR10','PR11','PR12']].assign(no = np.nan).values[aa.index, a1][a2])
elif val1==2:
Reslt_1 = np.append(Reslt_1,0)
a2=a2+1
.....................
# input data
#I have 60 columns and 10871 rows.
# For every row I am comparing any 1 item(lets say sv1) of set-1 with set-2 if corresponding flag column is 4 otherwise default zero.
set-1 set-2
3 6 11 31 22 23 14 17 19 1 with 1 14 3 23 6 11 31 17 9 19 22 10 #(Flag->) 4 4 4 4 4 4 4 4 2 4 4 2

Python 2.7 list comprehension number pyramid

I am trying to create the following number pyramid using nested list comprehension and string formatting.
1
2 4
3 6 9
4 8 12 16
5 10 15 20 25
6 12 18 24 30 36
7 14 21 28 35 40 47
I figured out how to create the pyramid using nested for loops but can't quite get it to work using list comprehension. Here is my code:
for n in range(1,8):
print
for x in range(n):
if x>0:
print '%2d' % (n+(n*x)),
else:
print '%d' % n,
The same code using list comprehension gives me a syntax error:
rows = [
'%2d' % (n+(n*x)), if x > 0 else '%d' % n,
for n in range(1,8)
for x in range(n)
]
print '\n' +'\n'.join(rows)
Any ideas on how to format the pyramid correctly using list comprehension?
You could use range to build up each nested list, like so:
# Generation
result = [range(x, x**2 + 1, x) for x in range(1, 8)]
# Formatting
print('\n'.join(''.join(str(x).ljust(4) for x in row) for row in result))
Output:
1
2 4
3 6 9
4 8 12 16
5 10 15 20 25
6 12 18 24 30 36
7 14 21 28 35 42 49
You can join a list of lists (in this case, a generator of generators) by newlines
print('\n'.join(' '.join(str(i*j) for j in range(1, i+1)) for i in range(1, n+1)))
#1
#2 4
#3 6 9
#4 8 12 16
#5 10 15 20 25
#6 12 18 24 30 36
#7 14 21 28 35 42 49
and if you want to have the list that creates it just do:
rows = [[i*j for j in range(1, i+1)] for i in range(1, n+1)]

To find the difference b/w two numbers in a column of file?

Consider a input file with 5 column(0-5):
1 0 937 306 97 3
2 164472 75 17 81 3
3 197154 35268 306 97 3
4 310448 29493 64 38 1
5 310541 29063 64 38 1
6 310684 33707 64 38 1
7 319091 47451 16 41 1
8 319101 49724 16 41 1
9 324746 61578 1 5 1
10 324939 54611 1 5 1
for the second column i,e column1(0,164472,197154-----------) need to find the difference b/w numbers so that the column1 should be (0,164472-0,197154-164472,____) so (0,164472,32682..............).
And the output file must change only the column1 values all other values must remain the same as input file:
1 0 937 306 97 3
2 164472 75 17 81 3
3 32682 35268 306 97 3
4 113294 29493 64 38 1
5 93 29063 64 38 1
6 143 33707 64 38 1
7 8407 47451 16 41 1
8 10 49724 16 41 1
9 5645 61578 1 5 1
10 193 54611 1 5 1
if anyone could suggest a python code to do this it would be helpfull........
Actually i tried to append all the columns into list and find the difference of column2 and again write back to another file.But the input file i have posed is just a sample the entire input file contains 50,000 lines so my attempt failed
The attempt code i tried is as follows:
import sys
import numpy
old_stdout = sys.stdout
log_file = open("newc","a")
sys.stdout = log_file
a1 = []; a2 = []; a2f = []; v = []; a3 = []; a4 = []; a5 = []; a6 = []
with open("newfileinput",'r') as f:
for line in f:
job = map(int,line.split())
a1.append(job[0])
a3.append(job[2])
a4.append(job[3])
a5.append(job[4])
a6.append(job[5])
a2.append(job[1])
v = [a2[i+1]-a2[i] for i in range(len(a2)-1)]
print a1
print v
print a3
print a4
print a5
print a6
sys.stdout = old_stdout
log_file.close()
Now from the output file of the code "newc" which contained 6 list i wrote it in to an file one by one...Which was time consuming.... & not so efficient...
So if anyone could suggest a simpler method it will be helpful..........
Try this. let me know if any problems or if you want me to explain any of the code:
import sys
log_file = open("newc.txt","a")
this_no, prev_no = 0, 0
with open("newfileinput.txt",'r') as f:
for line in f:
row = line.split()
this_no = int(row[1])
log_file.write(line.replace(str(this_no), str(this_no - prev_no)))
prev_no = this_no
log_file.close()
don't downvote me, just for fun.
import re
from time import sleep
p = re.compile(r'\s+')
data = '''1 0 937 306 97 3
2 164472 75 17 81 3
3 197154 35268 306 97 3
4 310448 29493 64 38 1
5 310541 29063 64 38 1
6 310684 33707 64 38 1
7 319091 47451 16 41 1
8 319101 49724 16 41 1
9 324746 61578 1 5 1
10 324939 54611 1 5 1\n''' * 5000
data = data.split('\n')[0:-1]
data = [p.split(one) for one in data]
data = [map(int, one) for one in data]
def list_diff(a, b):
temp = a[:]
temp[1] = a[1] - b[1]
return temp
result = [
data[0],
]
for i, _ in enumerate(data):
if i < len(data) - 1:
result.append(list_diff(data[i+1], data[i]))
for i, one in enumerate(result):
one[0] = i+1
print one
sleep(0.1)

Categories