Python 2d array issues - python

I have been given this as a list of lists each containing either a number 1 2 3 and 0 (0 is repeated twice). Depending on the number and the position I would like a corresponding variable to get added 1 time for each occurrence.
ballots = [['1', '2', '3', '0', '0'],
['1', '3', '0', '2', '0'],
['1', '2', '3', '0', '0'],
['0', '3', '2', '0', '1'],
['1', '3', '0', '2', '0'],
['2', '0', '3', '1', '0'],
['0', '0', '2', '1', '3'],
['0', '1', '2', '3', '0'],
['0', '1', '0', '2', '3'],
['2', '3', '1', '0', '0'],
['3', '2', '0', '0', '1'],
['0', '1', '3', '2', '0'],
['0', '0', '1', '2', '3'],
['0', '0', '3', '2', '1'],
['1', '2', '3', '0', '0'],
['2', '1', '3', '0', '0'],
['0', '3', '2', '1', '0'],
['0', '2', '3', '0', '1'],
['1', '2', '3', '0', '0'],
['1', '0', '0', '3', '2'],
['2', '1', '3', '0', '0'],
['3', '1', '2', '0', '0'],
['2', '3', '0', '1', '0'],
['0', '0', '3', '1', '2'],
['0', '3', '1', '0', '2'],
['2', '1', '0', '0', '3'],
['2', '0', '0', '1', '3'],
['2', '0', '0', '1', '3'],
['3', '0', '1', '0', '2']]
For example, for the first list:
the 1 in position 1 would mean that candidate1vote1 += 1
the 2 in the 2nd position would mean that candidate2vote2 += 1
the 3 in the 3rd position would mean that candidate3vote3 += 1
All 0's are ignored but still counted as a space. For the second list:
the 1 in the first position would mean that candidate1vote1 += 1
the 3 in the 2nd position would mean that candidate3vote2 += 1
the 2 in the 4th position would mean that candidate4vote2 += 1
Basically the position corresponds to candidate1/2/3/4/5 and the value corresponds to either a 1st preference vote, 2nd preference vote or a 3rd preference vote.
Does anyone know how I'd be able to sort through the lists using for/while loops so that it goes through each ballot and each individual vote doing the corresponding sum?

First want to clarify.. so you intend to collect not just votes for each candidate, but the vector of preference votes (1,2,3) for each candidate?
Understand you are dealing with nested list and how to index them. (you would use the term array for those types in numpy library)
when you index list, you access the data from outside to inside. e.g. [outer][inner] (outer/inner as there could be more than 2 nested list)
Now that you know this, given that you don't have memory/time constraints, and since you seem to be not so comfortable with python..I'd suggest you use double for loop. Let's make a nested list of candidate with preference. Their outer index will be candidate #, inner lists with preference.
len(ballot) gives you the # of rows, (let's just say for convenience) 5 you already have for columns. work out the indentation please..
candidate = [[0]*4 for n in xrange(5)] //depends on your choice - whether you want to count for number of 0s, if you want to match position and preference..
n = len(ballot)
for i in range(0, n): //python index starts with 0, if you use range it includes the start number but not the last. google if you don't know
for j in range(0, 5):
if ballots[i][j] == '1':
candidate[j][1] +=1
elif ballots[i][j] == '2':
candidate[j][2] +=1
elif ballots[i][j] == '3':
candidate[j][3] +=1
else: //0
candidate[j][0] +=1

Like this you can put each answer in a list:
c1= list()
c2= list()
...
for i in ballots:
c1.append(i[0])
c2.append(i[1])
...

Related

how to find a list in a bunch of lists in python

I want a way to make it so that I can use list B to find out if a copy of it's self exists in list A.
I want a way to make it so that I can use list B to find out if a copy of it's self exists in list A.
this is the way data a has been collected:
for i in range(len(fsa)):
if fsa[i] < fsb[i]:
kol.append('1')
else:
kol.append('0')
start = 0
end = len(fsa)
j = [ ]
for x in range(start, end, 6):
m = fsb[x:x+6]
t = kol[x:x+6]
if m[0] < m[-1]:
t.append('up')
else:
t.append('down')
j.append(t)
counter = Counter(tuple(j) for j in j)
for members, count, in counter.items():
print(list(members), count)
output:
listA = ['1', '1', '0', '1', '0', '1', 'down'] 2
['0', '0', '1', '1', '1', '1', 'up'] 2
['1', '0', '0', '1', '0', '1', 'up'] 1
['0', '0', '0', '1', '1', '0', 'up'] 2
['1', '1', '0', '0', '0', '0', 'up'] 1
['0', '0', '1', '1', '0', '1', 'down'] 1
['1', '0', '0', '0', '0', '1', 'down'] 1
['1', '1', '1', '1', '1', '1', 'up'] 1
this is how data b was collected:
for _ in range(num):
inner = driver.find_element_by_xpath("//html/body/div[1]/div[2]/div/div/div/div[2]/div/div[2]/div[2]/div/div/div[2]/div[4]/span[1]").get_attribute("innerHTML")
print(inner)
lok.append(inner)
time.sleep(20)#the hour
print(lok)
lokk = []
num = 7
for _ in range(num):
inner = driver.find_element_by_xpath("//html/body/div[1]/div[2]/div/div/div/div[2]/div/div[2]/div[2]/div/div/div[2]/div[4]/span[1]").get_attribute("innerHTML")
print(inner)
lokk.append(inner)
time.sleep(20)
print(lokk)
output:
listB = ['1', '1', '1', '1', '1', '1']
list A also shows how many times that particular list has appeared
so I want a way to first find the repeating list of list B in list A, secondly to select the one with the most repetitions in the case that there are multiple versions of it.
I tried a bunch of things but non really helped as i am still quite new at coding
As many pointed out, the code provided is not properly formatted, so I made some assumptions. Here is a half-solution to get you unstuck, try to modify this to get what you want. You will learn more by modifying this code than if I were to give you the final solution.
from collections import Counter # for comparing lists' content
from typing import List # for annotations
listA = [
['1', '1', '0', '1', '0', '1', 'down'],
['0', '0', '1', '1', '1', '1', 'up'],
['1', '0', '0', '1', '0', '1', 'up'],
['0', '0', '0', '1', '1', '0', 'up'],
['1', '1', '0', '0', '0', '0', 'up'],
['0', '0', '1', '1', '0', '1', 'down'],
['1', '0', '0', '0', '0', '1', 'down'],
['1', '1', '1', '1', '1', '1', 'up'],
]
listB = ['1', '1', '1', '1', '1', '1']
def find_match(metrix: List[List[str]], list_: List[str]) -> List[List[str]]:
list_counter = Counter(list_)
# Solution 1: Pythonic solution
matches = [match for match in metrix if Counter(match[:-1]) == list_counter]
# Solution 2: beginner friendly solution
# matches = []
# for m_list in metrix:
# if Counter(m_list[:-1]) == list_counter:
# matches.append(m_list)
return matches
# Complexities
# if n == metrix.length and m == metrix[0].length; then
# Time: O(nm);
# Space: O(nm);
print(find_match(listA, listB))
# outputs: [['1', '1', '1', '1', '1', '1', 'up']]
Here's something that works. Not sure if it's exactly what you want, but you can modify it to fit your needs.
Note that it assumes listB has the same length as the first part of each of listA elements (before "up"/"down").
listA =[
['1', '1', '0', '1', '0', '1', 'down', 2],
['0', '0', '1', '1', '1', '1', 'up', 2],
['1', '0', '0', '1', '0', '1', 'up', 1],
['0', '0', '0', '1', '1', '0', 'up', 2],
['1', '1', '0', '0', '0', '0', 'up', 1],
['0', '0', '1', '1', '0', '1', 'down', 1],
['1', '0', '0', '0', '0', '1', 'down', 1],
['1', '1', '1', '1', '1', '1', 'up', 1]
]
listB = ['1', '1', '1', '1', '1', '1']
listC = ['0','0','0','0','0','0']
def find_list(list1,list2):
index = -1
occ = 0
for i,l in enumerate(list2):
if l[:len(list1)]==list1:
if l[-1]>occ:
index = i
occ = l[-1]
if index == -1:
return "The 1st list doesn't appear in the 2nd one."
else:
return f"The 1st list appears in the 2nd one at index {index} with a number of occurences equal to {occ}."
print(find_list(listB, listA))
# The 1st list appears in the 2nd one at index 7 with a number of occurences equal to 1.
print(find_list(listC, listA))
# The 1st list doesn't appear in the 2nd one.

How to retrieve the position of a list in a list of lists in python

A = [['0', '6', '4', '3'], ['0', '2', '8', '3'], ['0', '4', '1', '5'], ['0', '3', '2', '5']]
B = ['0', '4', '1', '5']
Say I want to find out at which line does B equal to the list. How do I write a solution for this?
The answer would be the third line.
I tried doing a for loop.
You can try list.index(element) to get the index of the element in the original list (A). In your terminology, to get the line just add one to the index.
line = A.index(B) + 1
you dont need use loops.you can get the element index by indexing.
A = [['0', '6', '4', '3'], ['0', '2', '8', '3'], ['0', '4', '1', '5'], ['0', '3', '2', '5']]
B = ['0', '4', '1', '5']
print(A.index(B))
>>> 2

Python Index is out of bounds

I am cleaning up data in a .txt file. I use 3 different .txt. files to analyze and clean up three different constructs. The .txt files all have 10 respondents, the first and the last have 17 answers per respondent. The middle one has 16 answers per respondent. The problem I'm facing right now is that the first and last work, but the middle one with 16 questions has problems with the index. All three pieces of code look almost identical.
The error code:
Traceback (most recent call last):
File "main.py", line 161, in <module>
itemF = dataF[row,column]
IndexError: index 16 is out of bounds for axis 1 with size 16
Sample input:
['N.v.t.', '0', '1', '2', '1', 'N.v.t.', '0', '0', '2', '0', '0', '3', '2', '3', '1', '1']
['N.v.t.', '1', 'N.v.t.', '0', '0', 'N.v.t.', '2', '0', 'N.v.t.', '1', '0', '1', '1', '2', '0', '1']
['N.v.t.', '0', 'N.v.t.', '0', '0', 'N.v.t.', '0', '0', 'N.v.t.', '0', '0', '3', '0', '3', '0', '0']
['2', '2', 'N.v.t.', '1', '3', '1', '2', '1', '1', '3', '2', '2', '3', '1', '2', '3']
['1', '2', 'N.v.t.', '0', '0', 'N.v.t.', '2', '2', '0', '2', '1', '2', '2', '3', '1', '2']
['N.v.t.', '0', 'N.v.t.', '1', '0', 'N.v.t.', '1', '2', 'N.v.t.', '1', '0', '3', '1', '3', '2', '2']
['0', '3', 'N.v.t.', '0', '2', '3', '2', '1', '3', '2', '2', '2', '2', '3', '0', '1']
['1', '3', 'N.v.t.', '0', '2', 'N.v.t.', '0', '2', 'N.v.t.', '0', '1', '1', '0', '2', '2', '1']
['1', '2', '2', '2', '3', '3', '0', '2', '2', '2', '2', '2', '2', '2', '2', '1']
['1', '2', 'N.v.t.', '0', '2', 'N.v.t.', '1', '3', '2', '2', '1', '3', '2', '2', '2', '2']
The code:
import numpy
dataF = numpy.loadtxt("answersFEAR.txt", dtype = str, delimiter = ", ")
shapeF = dataF.shape
(shapeF[0] == 5)
print(dataF)
for i in range(0, shape[0]):
str1 = dataF[i, 0]
str2 = dataF[i, -1]
dataF[i, 0] = str1.replace('[', '')
dataF[i, -1] = str2.replace(']', '')
for column in range(0,shape[1]):
for row in range(0, shape[0]):
itemF = dataF[row,column]
dataF[rij,kolom] = itemF.replace("'", '')
dataF[dataF == 'N.v.t.'] = numpy.nan
print("DATA FEAR")
print(dataD)
scoresF = dataF[:,1:17]
scoresF = scoresF.astype(float)
average_score_fear = numpy.nanmean(scoresF, axis = 1)
print("")
print("AVERAGE SCORE FEAR")
print(average_score_fear)
The expected outcome should look like this (this is just one result):
["['1'" "'2'" "'2'" "'2'" "'3'" "'3'" "'0'" "'2'" "'2'" "'2'" "'2'" "'2'" '2'" "'2'" "'2'" "'1']"]
DATA FEAR
[['1', '2', '2', '2', '3', '3', '0', '2', '2', '2', '2', '2', '2', '2', '2', '1']]
AVERAGE SCORE FEAR

How to get length of all the tokens of all the list for a given input file in python?

Suppose I am having a list (L1) like this:
L1 = [['1', '0', '0', '0'], ['1', '0', '0', '0'], ['0', '0', '0', '1'], ['1', '0', '0', '0'], ['0', '0', '0', '1'], ['0', '0', '1', '0'], ['1', '0', '0', '0'], ['1', '0', '0', '0'], ['0', '0', '0', '1'], ['0', '0', '0', '1'], ['0', '0', '0', '1'], ['1', '0', '0', '0'], ['0', '0', '0', '1'], ['0', '0', '0', '1'], ['0', '0', '0', '1'], ['1', '0', '0', '0'], ['1', '0', '0', '0'],['0', '0', '0', '0']]
If I use len(L1), it return 18, which is the total number of lists for the given input.
What if I need to compute the total number of tokens for the input list? How to achieve this?
As each list is having 4 tokens separated by comma delimiter. Then for this the list is having a total of 72 tokens?
Does there exist any way to achieve this in Python 3? Any help is deeply appreciated!
For your simple example, just sum the lengths of the nested lists:
sum(map(len, L1))
This works because all you have is a single level of nesting; the outer list contains nothing but nested lists, each of which contains only strings. sum() with map() is a very fast method of getting the total lengths; everything is handled in C code, the Python evaluation loop doesn't have to step through a for loop here.
If you know that the inner lists only ever contain 4 elements each, you could also just calculate the total:
len(L1) * 4
This is faster still; no iteration needed at all to ask for each nested list object for their length. However, we are talking about .76 vs .07 microseconds here, hardly an issue in any Python program. The for loop approach as posted by Frame takes about twice as long, at 1.33 microseconds. Not exactly an eternity.
If your input is not regular (so a mix of lists at different levels of nesting), but otherwise only consists of lists of objects, you'd need to iterate and decide for each element what to do. Here is a stack-based function that'll count all the non-list elements in such a structure:
def total_length(irregular):
total = 0
stack = [irregular]
while stack:
ob = stack.pop()
if not isinstance(ob, list):
total += 1
else:
stack.extend(ob)
return total
The above can be extended to cover tuples, etc, by adding to the isinstance() test as needed.
Demo:
>>> L1 = [['1', '0', '0', '0'], ['1', '0', '0', '0'], ['0', '0', '0', '1'], ['1', '0', '0', '0'], ['0', '0', '0', '1'], ['0', '0', '1', '0'], ['1', '0', '0', '0'], ['1', '0', '0', '0'], ['0', '0', '0', '1'], ['0', '0', '0', '1'], ['0', '0', '0', '1'], ['1', '0', '0', '0'], ['0', '0', '0', '1'], ['0', '0', '0', '1'], ['0', '0', '0', '1'], ['1', '0', '0', '0'], ['1', '0', '0', '0'], ['0', '0', '0', '0']]
>>> sum(map(len, L1))
72
>>> irregular = ['foo', ['spam', 'ham'], ['bar', ['monty', 'python', ['eric', 'idle'], 'vikings'], 42]]
>>> total_length(irregular)
10
Try something like:
tokens = 0
for lst in L1:
tokens += len(lst)
print tokens
You can iterate over lists of lists and sum up all the occurrences.

Deleting one position to another position elements from list in python

I have a list like the one below and I would like to delete all entries between any word (inclusive) and the next '0' (exclusive).
So for example this list:
array = ['1', '1', '0', '3', '0', '2', 'Continue', '1', '5', '1', '4', '0', '7', 'test', '3', '6', '0']
should become:
['1', '1', '0', '3', '0', '2', '0', '7', '0']
You can also do it by using exclusively list comprehension:
array = ['1', '1', '0', '3', '0', '2', 'Continue', '1', '5', '1', '4', '0', '7', 'test', '3', '6', '0']
# Find indices of strings in list
alphaIndex = [i for i in range(len(array)) if any(k.isalpha() for k in array[i])]
# Find indices of first zero following each string
zeroIndex = [array.index('0',i) for i in alphaIndex]
# Create a list with indices to be `blacklisted`
zippedIndex = [k for i,j in zip(alphaIndex, zeroIndex) for k in range(i,j)]
# Filter the original list
array = [i for j,i in enumerate(array) if j not in zippedIndex]
print(array)
Output:
['1', '1', '0', '3', '0', '2', '0', '7', '0']
array = ['1', '1', '0', '3', '0', '2', 'Continue', '1', '5', '1', '4', '0', '7', 'test', '3', '6', '0']
res = []
skip = False #Flag to skip elements after a word
for i in array:
if not skip:
if i.isalpha(): #Check if element is alpha
skip = True
continue
else:
res.append(i)
else:
if i.isdigit(): #Check if element is digit
if i == '0':
res.append(i)
skip = False
print res
Output:
['1', '1', '0', '3', '0', '2', '0', '7', '0']
Kicking it old school -
array = ['1', '1', '0', '3', '0', '2', 'Continue', '1', '5', '1', '4', '0', '7', 'test', '3', '6', '0']
print(array)
array_op = []
i=0
while i < len(array):
if not array[i].isdigit():
i = array[i:].index('0')+i
continue
array_op.append(array[i])
i += 1
print(array_op)

Categories