How to create n lists in function of x python - python

I have a python code where I want to open N files, and for each file, get 3 separate lists for particulars in X and Y (the last one for weight).
I managed to read a file, and to store it in different lists which are stored in a "main" list which stores lists.
But when my code reads the second file, I did the same as the first with the same name of list. But when I print the main list, it shows me L2 L2 for example, instead of L1 L2
I know this is because I use the same list, x1 for the 2 files and so the variable just change in final list, but as of right now, I have no clue on how to get something working right.
Here's the code
import os
x1 = []
y1 = []
p1 = []
Xtotal = []
Ytotal = []
listcount = 0
def stockage(z):
compteur = 0
del x1[:]
del y1[:]
del p1[:]
for ligne in z :
if ligne[0:1]=='#':
pass
else:
if ligne[0:1]=='p':
p1.append(float(ligne[2:]))
else:
compteur = compteur + 1
if compteur%2 == 0 :
y1.append(float(ligne.rstrip()))
else:
x1.append(float(ligne.rstrip()))
Xtotal.append(x1)
Ytotal.append(y1)
print(Xtotal)
for fichier in os.listdir('data/'):
fichierOuvert = open("data/"+fichier, "r")
listetotale=stockage(fichierOuvert)
fichierOuvert.close()
print(Xtotal)
print(x1)
print(y1)
print(p1)
And here's a sample file which is used as an imput :
'#'This file contains points particulars and the line with p= its weight
'#'PointA :
p=20
12
22
'#PointB :'
34
26
'#PointC :'
28
98
'#PointD :'
97
54

The result you're getting for Xtotal currently looks something like this:
[x1, x1]
because you're adding the same list twice. So, when you make changes to x1, you make changes to every list in Xtotal. Using del doesn't change that. Instead, you want to create entirely new lists each time your function is called.
What you need to do is move the definitions of your lists (x1 = [], etc.) into your function (where you currently have del x1[:]), and get rid of the lines where you clear out those lists (remove del x1[:], del y1[:], etc.). You will then have to remove the lines printing x1, y1, and p1 from the end of your script, but you can accomplish the same thing by doing
print(Xtotal[-1])
print(Ytotal[-1])
instead.
If you also add a variable Ptotal in the same way you have Xtotal and Ytotal, then you will have access to p1 as well, in the same way.

Perhaps this example will demonstrate what is going on:
x1 = []
Xtotal = []
def make_some_data(length):
del x1[:]
x1.extend(range(length))
Xtotal.append(x1)
print(Xtotal)
for i in range(1,5):
make_some_data(i)
print(Xtotal)
#output
[]
[[0]]
[[0, 1], [0, 1]]
[[0, 1, 2], [0, 1, 2], [0, 1, 2]]
[[0, 1, 2, 3], [0, 1, 2, 3], [0, 1, 2, 3], [0, 1, 2, 3]]
>>> [id(item) for item in Xtotal]
[4386547144, 4386547144, 4386547144, 4386547144]
>>> [id(item)==id(x1) for item in Xtotal]
[True, True, True, True]
When you erase the content of the list x1 you also get rid of the data you previously generated, rendering any reference to it instead point to the new data you fill it up with, instead you need to use local variables to make new lists as you need them:
Xtotal = []
def make_some_data(length):
x1 = []
x1.extend(range(length))
Xtotal.append(x1)
print(Xtotal)
for i in range(1,5):
make_some_data(i)
print(Xtotal)
#output:
[]
[[0]]
[[0], [0, 1]]
[[0], [0, 1], [0, 1, 2]]
[[0], [0, 1], [0, 1, 2], [0, 1, 2, 3]]

Related

How to get the element from the other list, according to the values in the current list?

I have one list that keep the sequence of number like.
a_list = [1,1,0,1,0,1]
I have two options that I have an idea for.
I have another list that keep the number of elements to get from a_list like:
b = [[1,1,4]]
The output will be like this:
output: [[[1],[1],[0,1,0,1]]]
Or the other option.
I have another list that keep the positions that I want the others to get from that position up to that position like.
c = [[0,1,4]]
And, the output will be like this:
output: [[[1],[1],[0,1,0,1]]]
My Code is:
def split(the_list, combi_list):
j = 0
result_list = []
while j < len(combi_list):
re2 = []
for i in range(len(combi_list[j])):
ft = combi_list[j][i]
re2.append(the_list[:ft])
result_list.append(re2)
j += 1
del the_list[:ft]
return result_list
In the function split I pass a_list in the_list and b or c in combi_list
And I get this result:
For first option:
Input: [[1,1,4],[1,2,3]]
output: [[[1], [1], [1, 1, 0, 1]], [[0], [0, 1], [0, 1]]]
For second option:
Input: [[0,1,4],[0,1,3]]
output: [[[], [1], [1, 1, 0, 1]], [[], [0], [0, 1]]]
(Both of them also pass a_list as an arguments)
What options should I choose? Can u help me to correct my code? Thank you So Much!!!!
You could use a simple generator function:
a_list = [1,1,0,1,0,1]
b = [1,1,4]
def split(input, counts):
start = 0
for count in counts:
yield input[start:start+count]
start += count
print(list(split(a_list, b)))
Prints
[[1], [1], [0, 1, 0, 1]]
You can look into using a copy of the list and the .pop() command to treat the list like a stack. Read the first element of the list for however many items you want to retrieve.
from itertools import islice
a_list = [1, 1, 0, 1, 0, 1]
a_list_iter = iter(a_list)
lengths = [1, 1, 4]
print([list(islice(a_list_iter, length)) for length in lengths])
Output:
[[1], [1], [0, 1, 0, 1]]
>>>
You can use for loop to iterate from one list and use the index of one to get in other place.
for eg:
lst1 = [1,2,3,5,9] #the list which have index
lst2 = list(range(2,20,2)) #The other list who's values are needed to pull
new_lst = list()
for items in lst1:
new_lst.append(lst2[items])
#voila you got your list.
You can use list comprehensions:
[ [a_list[:p] for p in pos] for pos in b ]

python populating array using while loop

All I am trying to do is populate an array with numbers in order. So, array[0][0] = 0, array[0][1]=1, etc. Why is this not working? I cannot figure it out.
def populateArray(ar):
count = 0
i=0
j=0
while (i<len(ar)):
while (j<len(ar[i])):
ar[i][j] = count
count = count + 1
j=j+1
j=0
i=i+1
return ar
numColumns = input('how many columns?')
numRows = input('how many rows?')
arr = [[0]*int(numColumns)]*int(numRows)
arr=populateArray(arr)
print(arr)
when you initiate your arr variable, you are multiplying a list of lists with a number, this results in a "mess" because what you actually do it is to multiply only the reference of the first list (from your list of lists), so actually you have in your arr only one list and a bunch of reference to that list, to fix this you can do:
arr = [[0] * int(numColumns) for _ in range(int(numRows))]
or:
arr = [[0 for _ in range(int(numColumns))] for _ in range(int(numRows))]
after changing this in your code, for numRows = 3 and numColumns = 4 you get:
[[0, 1, 2, 3], [4, 5, 6, 7], [8, 9, 10, 11]]
When you use this syntax to create multi dimensional array
arr = [[0]*int(numColumns)]*int(numRows)
the reference of same element is created many times , so if you assign a value to one of them then you are basically changing all the elements because they all reference to the same data.
for ex :
arr = [[0]*int(numColumns)]*int(numRows)
arr[0][1]=2
print(arr)
output
[[0, 2], [0, 2], [0, 2], [0, 2]]
I only changed one element and this is the result .
you should use :
arr = [[0 for i in range(int(numColumns))] for j in range(int(numRows))]
arr[0][1]=2
print(arr)
output :
[[0, 2], [0, 0], [0, 0], [0, 0]]
You can do this:
numColumns = input('how many columns?')
numRows = input('how many rows?')
arr = [[i+j for i in range(int(numRows))] for j in range(int(numColumns))]
arr=populateArray(arr)
print(arr)
The problem with your code is that you append same array to the main array multiple times, like this [l, l, l] and l is a list.
So when ever you change an elemenet of l it will change all of ls in your list.
So, your code works fine but each time you change another list, all of previous list will be effected.
You can also make use of numpy for creating the structure, followed by using numpy.tolist() for converting it to a python list
import numpy as np
numColumns = int(input('how many columns?'))
numRows = int(input('how many rows?') )
arr = np.arange(numRows*numColumns).reshape(numRows, numColumns).tolist()
print(arr)

Trying to find the duplicates of a sum of a list

I am attempting to find the first set of duplicates in a list which is the sum of another list (should take a list such as [0,+1,+2,+1,-5,+1,+2] and return 0, because the sum of the list progressively [0,1,3,4,-1,0,2] has its first duplicate at 0). However, it seems to be returning wrong answers no matter what I do. Here's my code:
sourceList = [+11,+16,+2,-16,-6,+13,-6,-8,-17,+15,-11,-14,+17,-9,+4,+1,-15,-17,-8,+16,+6,-11,-15,-2,+3,-6,-2,-4,-2,-18,-6,-2,+18,-4,+7,+15,-11,+8,-4,-17,-19,-15,-17,-7,+12,-2,-5,-13,-4,-13,-18,+16,+12,+10,+14,-19,+13,+10,+8,-10,+3,-16,-7,-9,-19,-15,-19,+2,+7,-1,+7,+1,-20,-5,-10,+14,+10,+5,+13,+10,+15,+3,-16,-17,+19,+15,+2,+14,-11,+3,-11,-17,-8,+16,-13,-1,+16,+1,+12,-5,+20,+16,+10,-9,-8,+15,-4,+3,+5,+7,+1,-2,+19,+14,-5,-10,-4,+3,+18,-15,+17,-7,+10,-8,-10,+4,+10,+12,+11,-4,-4,-8,+11,+16,-4,+14,+2,+3,-16,+19,-9,+5,+17,+19,-17,-4,+13,+15,-6,+20,+12,+15,-17,+13,-7,-14,+11,+12,-10,+16,-10,+8,+11,-8,+16,+5,+3,-4,+15,-16,+4,+2,+5,+8,+12,+7,+8,+4,+19,-14,+2,+8,+12,-14,+19,+15,-14,-17,-5,+7,-20,-5,-4,+14,-21,+4,-8,-7,+14,-18,-7,-18,-13,-19,-8,+16,+3,-8,+14,+10,+9,+18,-15,+14,-1,+18,+15,+17,+11,+16,-11,+7,-13,-14,-6,-11,+13,-12,-2,+9,-12,+10,-18,-6,-8,+9,+3,+6,+11,+15,+15,+5,+19,+15,+8,-12,-17,-8,+19,+2,+9,+2,+6,-10,-22,-9,+19,-5,-4,+3,+14,-1,-20,+15,+17,-1,+19,-8,+11,-13,+17,+9,+9,+18,+7,-8,+11,+16,+9,-1,+15,+19,-25,+1,-6,+8,-4,+13,-23,+15,+3,-14,+1,+25,+51,-11,+5,+5,-13,+17,+13,+16,+17,+17,+18,+16,+16,-5,-20,-19,+15,-14,-15,-6,+9,-1,-5,-13,-24,+13,-18,-29,+3,+10,-14,+29,-21,+11,+13,+24,+23,-17,+19,-1,-7,-5,+20,+5,-11,+3,-20,-13,+5,-12,-8,+4,-23,-31,+18,-50,-27,-16,+15,-21,-26,-11,-46,-11,-12,-5,-1,-6,+3,+19,+7,+33,+9,+11,+14,+32,+36,+15,-92,+22,-19,-18,-8,-24,+28,-72,+15,-19,-34,-4,-11,-4,+17,+14,-26,-23,-18,-10,-1,+39,-5,+19,+16,+26,-25,-40,-11,+19,-11,+1,+7,-55,-21,+73,+503,+843,+54936,+14,-12,+13,-7,-11,+8,+11,+11,+7,+13,+12,+9,+12,+1,+7,-19,-3,-5,-1,-20,+12,+11,-10,-8,-6,+17,+19,+1,+10,-19,+4,+19,+6,+4,+3,+6,+4,+12,+3,+2,-9,+3,+9,-15,-10,-9,-10,+4,+19,+11,+19,+2,+5,+9,-15,+12,+5,+9,+18,-12,-4,+7,+13,-6,+16,+16,+12,-7,+18,+3,+15,-12,+8,-19,+3,+3,+11,-3,+17,-10,+3,-20,+6,-17,+9,+16,+18,+8,-10,-12,+13,+7,-2,-11,+10,-2,+1,-5,+10,+13,-7,+14,+17,-1,-1,+8,-4,+16,-3,+16,+17,+4,+13,-3,+8,-15,-12,+14,+16,-5,-7,+14,-12,-17,-21,-1,-16,+4,+7,-14,-12,+16,-12,-12,-8,-3,-2,-4,+16,-14,+8,+18,-8,-2,-13,+2,+17,+15,+13,+12,-4,+19,-8,-6,+5,-16,+14,-15,-18,+13,+19,-9,+23,-5,-7,+5,+12,+18,-1,+20,-7,-6,-9,-11,+6,-5,+1,+7,+14,-2,+7,+2,+14,-3,-9,+15,-2,+12,+4,-5,+8,+9,-4,+2,+13,-4,-4,-10,+4,-2,+13,-2,-12,+26,+2,+17,+20,+20,+5,-21,+12,-5,-14,+4,+12,+9,-14,-1,+10,-5,-14,-5,-17,-12,-8,+12,+11,-9,+18,+2,-12,+7,+6,-8,+6,-18,-21,-8,+1,+12,-25,-11,+4,-16,-10,+19,+12,-10,-1,-24,-7,+4,+9,-4,-19,+28,+1,+5,-8,-18,+8,-29,-26,-17,+4,-19,-8,-6,+8,+15,+36,-6,-5,-18,+6,-4,-19,-4,-11,+3,-16,-1,+2,+13,+21,-10,+32,+28,+5,+21,-36,-11,-90,-11,+17,-11,+10,+3,+2,+11,-25,-17,-9,-9,+20,-17,-19,-17,-1,+6,-2,+10,-12,+5,-9,+12,+16,+3,-18,+1,+15,-3,-8,+15,+18,+11,+5,-20,-12,+6,-3,-13,+19,-17,+19,-23,+1,-14,+20,+13,+7,+3,-21,-17,-23,-8,-18,+16,+5,+7,-6,-9,-19,-18,+17,+17,-22,+17,+15,-12,-9,-9,+14,-9,-9,+3,-8,-7,-23,+7,+22,+37,+14,+22,-20,-9,-23,+18,-8,-5,+9,-13,+25,+8,-28,+23,-39,-8,-51,-30,+3,-31,+1,+4,+172,+17,+18,-30,+18,+47,+19,-24,-14,+117,-5,+168,+14,-16,-61,+1728,+54439,-8,+15,+5,-2,-1,-12,-3,+10,+15,+10,-14,+15,-8,+11,+10,-12,+11,+12,+17,-10,-6,-19,-19,+18,-12,-3,-7,-11,-13,-10,+9,-13,+9,-15,+16,+2,+16,+13,-17,+19,+16,+16,-10,-12,-7,+5,-15,+14,+19,-12,+17,+8,-18,+17,-4,+1,+6,-13,-5,+23,-19,-8,-13,-31,-12,-3,+5,-3,+11,-1,-20,-8,+5,-2,-2,-18,+1,-19,-5,-3,+13,+15,+10,-8,-14,+16,-14,+18,-11,+6,-10,-4,+5,-15,+8,-17,-7,-12,-12,+10,+6,-12,-17,+1,+8,+17,+17,-11,+19,-18,+1,-14,-2,-15,-6,-1,-16,+1,-3,+6,-18,+1,-17,+8,+19,+18,-5,+12,+6,-15,+19,-8,-16,+18,+15,-6,+1,-17,-10,-4,-112437]
sumList = []
histList = []
for x in sourceList:
print(str(sumList) + " is list a")
print(str(histList) + " is list b")
print(str(sum(sumList)) + " is the sum of list a")
if sum(sumList) in histList:
print(str(sum(sumList)) + " is the answer!")
break
else:
histList.append(sum(sumList))
sumList.append(sourceList[x])
One way to do this would be to use itertools.accumulate to build the list of accumulated sums for each position in the list. We'll add each to a set as we go, checking if it already exists:
from itertools import accumulate
def get_dupe(sourcelist):
exists = set()
for val in accumulate(sourcelist):
if val in exists:
return val
exists.add(val)
return None
get_dupe([0,+1,+2,+1,-5,+1,+2])
# 0
Your sourcelist will return None, because there are no repeated values in the accumulated sums. Counter(accumulate(sourcelist)).most_common(1) has a count of 1.
From what you're doing, it seems like sumList is the "current" list (that is, the portion of sourceList that you've iterated over). If so, you need to append x (and not sourceList[x] as x is not the index but the number in sourceList). Next, you need to append x to sumList before you check histList:
sourceList = [0,+1,+2,+1,-5,+1,+2]
sumList = []
histList = []
for x in sourceList:
sumList.append(x)
print(sumList, histList)
if sum(sumList) in histList:
print(str(sum(sumList)) + " is the answer!")
break
histList.append(sum(sumList))
Output
[0] []
[0, 1] [0]
[0, 1, 2] [0, 1]
[0, 1, 2, 1] [0, 1, 3]
[0, 1, 2, 1, -5] [0, 1, 3, 4]
[0, 1, 2, 1, -5, 1] [0, 1, 3, 4, -1]
0 is the answer!

Python Recursion List ( pop vs [ ] )

I am working on recursion and I have a problem that I have solved but I would like to know what is going on and why the way I tried first does not work. The only issue I have is emptying the listOfX when it has a length of 3.
Here is the original code that does not work as expected:
sol = []
def recLoop(levelWidth,levelOn,listOfX):
if len(listOfX) == 3:
sol.append([listOfX[0],listOfX[1]])
sol.append([listOfX[0],listOfX[2]])
listOfX = [] #THIS DOES NOT WORK
print listOfX
if len(levelWidth) != levelOn:
for x in range(levelWidth[levelOn]):
listOfX.append(x)
recLoop(levelWidth,levelOn+1,listOfX)
recLoop([3,2],0,[])
print sol
However it works as expected when I use pop() instead like this:
sol = []
def recLoop(levelWidth,levelOn,listOfX):
if len(listOfX) == 3:
sol.append([listOfX[0],listOfX[1]])
sol.append([listOfX[0],listOfX[2]])
listOfX.pop()
listOfX.pop()
listOfX.pop()
print listOfX
if len(levelWidth) != levelOn:
for x in range(levelWidth[levelOn]):
listOfX.append(x)
recLoop(levelWidth,levelOn+1,listOfX)
recLoop([3,2],0,[])
print sol
NOTE: the outcome of the first code is:
[[0, 0], [0, 1]]
but it should be:
[[0, 0], [0, 1], [1, 0], [1, 1], [2, 0], [2, 1]]
The statement:
listOfX = []
simply rebinds the local variable (which is just a reference to an object) to a new list. The original list object is still referenced elsewhere but not affected by this rebinding. Using listOfX.pop() on the other hand directly manipulates that object.
You can use:
listOfX[:] = []
to clear the list, instead.

Python index error value not in list...on .index(value)

I am a beginner at Python, and to those who holds negative thoughts against my post, please leave. I am simply seeking help here and trying to learn. I'm trying to check within a simple data set the 0s and 1s. This will be used towards defining voids and solids on floor plans to define zones in buildings... eventually 0s and 1s will be swapped out with coordinates.
I am getting this error: ValueError: [0, 3] is not in list
I am simply checking if one list is contained in the other.
currentPosition's value is [0, 3]
subset, [[0, 3], [0, 4], [0, 5], [1, 3], [1, 4], [1, 5], [2, 1], [3, 1], [3, 4], [3, 5], [3, 6], [3, 7]]
Here's the code snippet:
def addRelationship(locale, subset):
subset = []; subSetCount = 0
for rowCount in range(0, len(locale)):
for columnCount in range (0, int(len(locale[rowCount])-1)):
height = len(locale)
width = int(len(locale[rowCount]))
currentPosition = [rowCount, columnCount]
currentVal = locale[rowCount][columnCount]
print "Current position is:" , currentPosition, "=", currentVal
if (currentVal==0 and subset.index(currentPosition)):
subset.append([rowCount,columnCount])
posToCheck = [rowCount, columnCount]
print "*********************************************Val 0 detected, sending coordinate to check : ", posToCheck
newPosForward = checkForward(posToCheck)
newPosBackward = checkBackward(posToCheck)
newPosUp = checkUpRow(posToCheck)
newPosDown = checkDwnRow(posToCheck)
I am using subset.index(currentPosition) to check and see if [0,3] is in subset but getting the [0,3] is not in list. How come?
Let's show some equivalent code that throws the same error.
a = [[1,2],[3,4]]
b = [[2,3],[4,5]]
# Works correctly, returns 0
a.index([1,2])
# Throws error because list does not contain it
b.index([1,2])
If all you need to know is whether something is contained in a list, use the keyword in like this.
if [1,2] in a:
pass
Alternatively, if you need the exact position but don't know if the list contains it, you can catch the error so your program does not crash.
index = None
try:
index = b.index([0,3])
except ValueError:
print("List does not contain value")
Why complicate things
a = [[1,2],[3,4]]
val1 = [3,4]
val2 = [2,5]
check this
a.index(val1) if val1 in a else -1
a.index(val2) if val2 in a else -1
subset.index(currentPosition) evaluates False when currentPosition is at index 0 of subset, so your if condition fails in that case. What you want is probably:
...
if currentVal == 0 and currentPosition in subset:
...
I found out that
list = [1,2,3]
for item in range(len(list)):
print(item)
won't work because it starts at 0, so you need to write
for item in range(1, len(list)):
print(item)

Categories

Resources