trying to find out places located within list - python

For example I am looking for a way to search every spot in a list to see where an object is located. Some example psuedocode could go:
for every column in current row:
if column is the first one:
do this
if column in the last one:
do that
else:
find the previous row and columns place
Basically I am at a standstill so any insight would be helpful thanks
EDIT Sample Code:
for row in range(0,h+1):
newrow=[]
if row==0:
newrow=[1]
elif row==1:
newrow=[1,1]
else:
for column,x in enumerate(row):
if column==0:
newrow.append(1)
elif column==len(row)-1:
newrow.append(1)
else:
newrow.append(2)

Are you looking for list.index?
l = ['foo', 'bar', 'baz']
i = l.index('bar')
# i is 1, because l[1] == 'bar'
If you need special handling based on whether it's the first or last item:
# using i from above
if i == 0:
# it's the first item
elif i == len(l) - 1:
# it's the last item
else:
# it's neither first nor last
Or if you need to process all items anyway, consider using enumerate to keep track of indices throughout the loop:
for i, x in enumerate(mylist):
if i == 0:
# x is the first item
elif i == len(mylist)-1:
# x is the last item
else:
# x is in the middle

bardockyo:
The problem appears to be that you don't have a list in row... when you run the code 'for row in range(0,h+1):', row will always be an integer with a value between greater than or equal to 0, and less than or equal to h.
Are you trying to read a file a row at a time, and keep track of the row numbers? If so, you should use a separate counter to track the row number...
I can't quite follow what you're trying to accomplish, so I can't even generate code to help you...
Added in response to bardockyo's comment:
I believe this accomplishes your goal:
# Setting h to a value so that I can use your 'range' line.
h = 5
# Create a blank dictionary object to store the row data.
rows = {}
for row_number in range(0,h+1):
row_data = []
# range isn't inclusive of the end value by default, to 'make it work', we
# must add 1 to the row_number.
for val in range(0,row_number+1):
if val == 0 or val == row_number:
# Determine if the value in 'val' is either the first number or
# last number in this row, and if so append '1' to the list.
row_data.append(1)
else:
# Determine if the value in 'val' is not the first number or last
# number in this row, and if so append '2' to the list.
row_data.append(2)
# Store the row data in the row dictionary, with the key of 'row_number'.
rows[row_number] = row_data
# Iterate through the dictionary. There's no guarantee as to the order
# returned by the 'keys()' function, so I use sorted() to ensure it's in
# numerical order.
for row_num in sorted(rows.keys()):
print 'Row Number %d contains the list:' % row_num,
for val in rows[row_num]:
print '%d' % val,
print ''
# There are better (read: cleaner) ways to format the output for printing,
# but they can be hard to read.

Related

How to split a Python array at every occurrence of a given string?

I am making up a code in Python 3.7 in which I need to split an array in chunks.
The array is something similar to the following one:
['1.60500002', '1.61500001', '1.625', '1.63499999','NO',
'1.73500001','1.745', 'NO','2.04500008', '2.05499983']
I am interested to create n different slices (3 in this case) everytime the string 'NO' occurs. Then the output array should be something like:
[['1.60500002', '1.61500001', '1.625', '1.63499999'],
['1.73500001', '1.745'],
['2.04500008', '2.05499983']]
Could someone help me?
You can try iterating through the list, checking if the element is a floating point number and if so adding it to a list and if not creating a new list. Just add up all the lists you've made and that should be it.
def split_str(inp):
array_of_array = []
arr = []
for a in inp:
try:
float(a)
arr.append(a)
except Exception:
array_of_array.append(arr)
arr = []
array_of_array.append(arr)
return array_of_array
loop over the array and if the element is "NO", we split the array until the "NO" element and add it to the output. if we reached the end, the last part would be from the last "NO" to the end.
my_array = ['1.60500002', '1.61500001', '1.625', '1.63499999','NO','1.73500001', '1.745', 'NO','2.04500008', '2.05499983']
output = []
counter = 0
start = 0
for item in my_array:
if item == "NO":
output.append(my_array[start:counter])
start = counter + 1
if counter == len(my_array) - 1:
output.append(my_array[start:counter + 1])
counter += 1
Since the only split indicator is 'NO' this should be easier. All you have to do is check for 'NO' and then create a new list. You also have to handle for the first element scenario as it can be a 'NO' or a number but creation of a new list if it is 'NO' is not required
To create a new list inside a list, you can do examplelist.append([])
Then to access a specific list inside a list, you can mention the list number in square brackets before using append(). eg. examplelist[list_number].append(whatever)
Here is the code I came up with :
#Input
array = ['1.60500002', '1.61500001', '1.625', '1.63499999','NO','1.73500001', '1.745', 'NO','2.04500008', '2.05499983']
#Declaring
result = [] #empty list
list_number = 0 #to access a specific list inside a list
starting_element = True #var to handle starting scenario
for element in array:
#starting scenario
if starting_element:
result.append([])
if element != 'NO':
result[list_number].append(element)
starting_element = False
#NO scenario
elif element == 'NO':
list_number += 1
result.append([])
#Number scenario
elif element != 'NO':
result[list_number].append(element)
print(result)

How do I write the index for a list of lists

I have a list of 3 lists each containing a random integer between 1 and 9:
lists= [[1,3,5],[2,4,6],[7,8,9]]
I ask the user to select any single digit number. I am making a program that finds the number one less than the user inputs and then decides if the next number in the list (assuming it is not the end of the list) is bigger or smaller.
for x in lists:
for i in x:
if i= user_choice-1:
Here I am stuck.
Lets say the user_choice is 3. I want the program to find the number 3-1=2 in the nested lists and then compare the number following 2 (in this case 4) to the user_choice.
if your list is
lists= [[1,3,5],[2,4,6],[7,8,9]]
to access the "1" you would type: lists[0][0]
to access the "8" you would type: lists[2][1]
*remember lists start their index at 0!!! :)
I am a little confused by what you are trying to achieve but you can get the index along with the element in a for loop by using:
for index, value in enumerate(my_list):
# Do stuff here
Or you can find the index of any element in a list with:
index = my_list.index(value)
Don't forget to change you = to a == in your if statement, by the way.
If I understand correctly, you want:
for x in lists:
for i in range(len(x)):
if x[i] == user_choice-1 and i < len(x)-1:
if x[i+1] > x[i]:
#Next value is bigger...
else:
#Next value is smaller...
lists= [[1,3,5],[2,4,6],[7,8,9]]
for x in lists:
index = 0
for i in x:
index += 1
if i == user_choice - 1:
print(x[index])
else:
(...)

print unique numbers from a sorted list python

I'm trying to print all elements in a sorted list that only occur once.
My code below works but I'm sure there is a better way:
def print_unique(alist):
i = 0
for i in range(len(alist)):
if i < (len(alist)-1):
if alist[i] == alist[i+1]:
i+=1
if alist[i] == alist[i-1]:
i+=1
elif alist[i] == alist[i-1]:
i+=1
else:
print alist[i]
else:
if alist[-1]!= alist[-2]:
print alist[-1]
randomlist= [1,2,3,3,3,4,4,5,6,7,7,7,7,8,8,8,9,11,12,14,42]
print_unique(randomlist)
This produces
1
2
5
6
9
11
12
14
42
e.g. all values that only appear once in a row.
You could use the itertools.groupby() function to group your inputs and filter on groups that are one element long:
from itertools import groupby
def print_unique(alist):
for elem, group in groupby(alist):
if sum(1 for _ in group) == 1: # count without building a new list
print elem
or if you want to do it 'manually', track the last item seen and if you have seen it more than once:
def print_unique(alist, _sentinel=object()):
last, once = _sentinel, False
for elem in alist:
if elem == last:
once = False
else:
if once:
print last
last, once = elem, True
if last is not _sentinel and once:
print last
You may want to replace the print statements with yield and leave printing to the caller:
def filter_unique(alist):
for elem, group in groupby(alist):
if sum(1 for _ in group) == 1: # count without building a new list
yield elem
for unique in filter_unique(randomlist):
print unique
This question seems to have duplicates.
If you do not wish to preserve the order of your list, you can do
print list(set(sample_list))
You can also try,
unique_list = []
for i in sample_list:
if i not in unique_list:
unique_list.append(i)
EDIT:
In order to print all the elements in the list so that they appear once in a row, you can try this
print '\n'.join([str(i) for i in unique_list])
And, as #martijn-pieters mentioned it in the comments, the first code was found to be very fast compared to the second one, when I did a small benchmark. On a list of 10^5 elements, the second code took 63.66 seconds to complete whereas the first one took a mere 0.2200 seconds. (on a list generated using random.random())
you can do by this:
print (set(YOUR_LIST))
or if you need a list use this:
print (list(set(YOUR_LIST)))
Sets are lists containing unique items. If you construct a set from the array, it will contain only the unique items:
def print_unique(alist):
print set( alist )
The input list does not need to be sorted.

Python - Find matching elements between and within nested lists

Background: I have a lengthy script which calculates possible chemical formula for a given mass (based on a number of criteria), and outputs (amongst other things) a code which corresponds to the 'class' of compounds which that formula belong to. I calculate formula from batches of masses which should all be members of the same class. However, given instrumentation etc limits, it is possible to calculate several possible formula for each mass. I need to check if any of the classes calculated are common to all peaks, and if so, return the position of the match/etc.
I'm struggling with working out how to do an iterative if/for loop which checks every combination for matches (in an efficient way).
The image included summarises the issue:
Or on actual screenshots of the data structure:
image link here -
As you can see, I have a list called "formulae" which has a variable number of elements (in this case, 12).
Each element in formulae is a list, again with a variable number of elements.
Each element within those lists is a list, containing 15 7 elements. I wish to compare the 11th element amongst different elements.
I.e.
formulae[0][0][11] == formulae[1][0][11]
formulae[0][0][11] == formulae[1][1][11]
...
formulae[0][1][11] == formulae[11][13][11]
I imagine the answer might involve a couple of nested for and if statements, but I can't get my head around it.
I then will need to export the lists which matched (like formulae[0][0]) to a new array.
Unless I'm doing this wrong?
Thanks for any help!
EDIT:
1- My data structure has changed slightly, and I need to check that elements [?][?][4] and [?][?][5] and [?][?][6] and [?][?][7] all match the corresponding elements in another list.
I've attempted to adapt some of the code suggested, but can't quite get it to work...
check_O = 4
check_N = 5
check_S = 6
check_Na = 7
# start with base (left-hand) formula
nbase_i = len(formulae)
for base_i in range(len(formulae)): # length of first index
for base_j in range(len(formulae[base_i])): # length of second index
count = 0
# check against comparison (right-hand) formula
for comp_i in range(len(formulae)): # length of first index
for comp_j in range(len(formulae[comp_i])): # length of second index
if base_i != comp_i:
o_test = formulae[base_i][base_j][check_O] == formulae[comp_i][comp_j][check_O]
n_test = formulae[base_i][base_j][check_N] == formulae[comp_i][comp_j][check_N]
s_test = formulae[base_i][base_j][check_S] == formulae[comp_i][comp_j][check_S]
na_test = formulae[base_i][base_j][check_Na] == formulae[comp_i][comp_j][check_Na]
if o_test == n_test == s_test == na_test == True:
count = count +1
else:
count = 0
if count < nbase_i:
print base_i, base_j, comp_i,comp_j
o_test = formulae[base_i][base_j][check_O] == formulae[comp_i][comp_j][check_O]
n_test = formulae[base_i][base_j][check_N] == formulae[comp_i][comp_j][check_N]
s_test = formulae[base_i][base_j][check_S] == formulae[comp_i][comp_j][check_S]
na_test = formulae[base_i][base_j][check_Na] == formulae[comp_i][comp_j][check_Na]
if o_test == n_test == s_test == na_test == True:
count = count +1
else:
count = 0
elif count == nbase_i:
matching = "Got a match! " + "[" +str(base_i) + "][" + str(base_j) + "] matches with " + "[" + str(comp_i) + "][" + str(comp_j) +"]"
print matching
else:
count = 0
I would take a look at using in such as
agg = []
for x in arr:
matched = [y for y in arr2 if x in y]
agg.append(matched)
Prune's answer not right, should be like this:
check_index = 11
# start with base (left-hand) formula
for base_i in len(formulae): # length of first index
for base_j in len(formulae[base_i]): # length of second index
# check against comparison (right-hand) formula
for comp_i in len(formulae): # length of first index
for comp_j in len(formulae[comp_i]): # length of second index
if formulae[base_i][base_j][check_index] == formulae[comp_i][comp_j][check_index]:
print "Got a match"
# Here you add whatever info *you* need to identify the match
I'm not sure I fully understand your data structure, hence I'm not gonna write code here but propose an idea: how about an inverted index?
Like you scan once the lists creating kind of a summary of where the value you look for is.
You could create a dictionary composed as follows:
{
'ValueOfInterest1': [ (position1), (position2) ],
'ValueOfInterest2': [ (positionX) ]
}
Then at the end you can have a look at the dictionary and see if any of the values (basically lists) have length > 1.
Of course you'd need to find a way to create a position format that makes sense to you.
Just an idea.
Does this get you going?
check_index = 11
# start with base (left-hand) formula
for base_i in len(formulae): # length of first index
for base_j in len(formulae[0]): # length of second index
# check against comparison (right-hand) formula
for comp_i in len(formulae): # length of first index
for comp_j in len(formulae[0]): # length of second index
if formulae[base_i][base[j] == formulae[comp_i][comp_j]:
print "Got a match"
# Here you add whatever info *you* need to identify the match

Python number to word converter needs a space detector

I have been working on a sort of encryption tool in python. This bit of code is for the decryption feature.
The point is to take the given numbers and insert them into a list from where they will be divided by the given keys.
My idea for code is below but I keep getting the out of list index range whenever I try it out. Any suggestions? Keep in mind I'm a beginner:
need = []
detr = raw_input('What would you like decrypted?')
count = 0
for d in detr:
if (d == '.' or d == '!') or (d.isalpha() or d== " "):
count +=1
else:
need[count].append(d)
The problem is you are attempting to overwrite list values that don't exist.
list.append(item) adds item to the end of list. list[index] = item inserts item into list at position index.
list = [0,0,0]
list.append(0) # = [0,0,0,0]
list[0] = 1 # [1,0,0,0]
list[99] = 1 # ERROR: out of list index range
You should get rid of the count variable entirely. You could append None in the case of d==' ' etc. or just ignore them.
The way I understood your description you want to extract the numbers in a string and append them to a list using a for-loop to iterate over each character.
I think it would be easier doing it with regular expressions (something like r'([\d]+)').
But the way joconner said: "get rid of the count variable":
need = []
detr = input('What would you like decrypted?\n')
i = iter(detr) # get an iterator
# iterate over the input-string
for d in i:
numberstr = ""
try:
# as long as there are digits
while d.isdigit():
# append them to a cache-string
numberstr+= d
d = next(i)
except StopIteration:
# occurs when there are no more characters in detr
pass
if numberstr != "":
# convert the cache-string to an int
# and append the int to the need-array
need.append( int(numberstr) )
# print the need-array to see what is inside
print(need)

Categories