Fastest way to check if a list pattern is present in another list of varying lengths? - python-3.x

Suppose I have a list of lists of varying lengths.
list1 = [['0', '0'],['0', '1', '0', ' '],['0', '1', ' ', '0', '1', ' '],['1', '1', ' ', ' ', '1', '1', ' ', '0'],[]]
I want to compare this list against another list of lists:
list2=[['0','0','0','0'],['1','1','1','1']]
Now, I want to check if list2 is contained in list1. The output should be True since list1 has ['1', '1', ' ', ' ', '1', '1', ' ', '0'] which contains ['1','1','1','1']
What would be the best way to check if any of the list2 elements are present in list1? The answer should be a Boolean in case any of the list2 elements are found in list1 by maintaining order.
I have tried quite a few things, but can't seem to get the desired output. Thanks in advance for the suggestions.

This will do the trick
list1 = [['0', '0'], ['0', '1', '0', ' '], ['0', '1', ' ', '0', '1', ' '], ['1', '1', ' ', ' ', '1', '1', ' ', '0'], []]
list2 = [['0', '0', '0', '0'], ['1', '1', '1', '1']]
for i in list2:
string2 = ''.join(i)
for j in list1:
string1 = ''.join(j).replace(' ','')
if string2 in string1:
print('yes',i,j)
# output yes ['1', '1', '1', '1'] ['1', '1', ' ', ' ', '1', '1', ' ', '0']

Simplistic approach:
list1 = [['0', '0'],['0', '1', '0', ' '],['0', '1', ' ', '0', '1', ' '],
['1', '1', ' ', ' ', '1', '1', ' ', '0'],[]]
list2 = [['0','0','0','0'],['1','1','1','1']]
# computing the shortened strings once, storing as string,orignal - tuples
texts = [(''.join(inner).replace(" ",""),inner) for inner in list1]
find = [(''.join(inner).replace(" ",""),inner) for inner in list2]
for (shortened,inner) in texts:
for (pattern,f) in find:
if pattern in shortened:
print("Found", f , "in", inner)
to get
Found ['1', '1', '1', '1'] in ['1', '1', ' ', ' ', '1', '1', ' ', '0']
It is simplistic because it is a quadratic search.

Related

While swapping in python using rindex for this specific case why swapping is not happening?

While swapping in python using rindex for this specific case why swapping is not happening? Case-1 is giving correct ans, but not case-2.
Case-1:
S=['1', '1', '1', '2', '1', '1']
S[S.index('1')], S[''.join(S).rindex('2')] = S[''.join(S).rindex('2')], S[S.index('1')]
print(S)
Output: ['2', '1', '1', '1', '1', '1']
Case-2:
S=['2', '1', '1', '1', '1', '1']
S[S.index('1')], S[''.join(S).rindex('2')] = S[''.join(S).rindex('2')], S[S.index('1')]
print(S)
Output: ['2', '1', '1', '1', '1', '1']
But Expected Output: ['1', '2', '1', '1', '1', '1']
Calculate your indices before doing the swap, not in the middle of it:
index1, index2 = S.index('1'), ''.join(S).rindex('2')
S[index1], S[index2] = S[index2], S[index1]

How to compare particular element in list python3?

l1= [['1', 'apple', '1', '2', '1', '0', '0', '0'], ['1',
'cherry', '1', '1', '1', '0', '0', '0']]
l2 = [['1', 'cherry', '2', '1'],
['1', 'plums', '2', '15'],
['1', 'orange', '2', '15'],
['1', 'cherry', '2', '1'],
['1', 'cherry', '2', '1']]
output = []
for i in l1:
for j in l2:
if i[1] != j[1]:
output.append(j)
break
print(output)
Expected Output:
[['1', 'plums', '2', '15'], ['1', 'orange', '2', '15']]
How to stop iteration and find unique elements and get the sublist?
How to stop iteration and find unique elements and get the sublist?
To find the elements in L2 that are not in L1 based on the fruit name:
l1= [[1,'apple',3],[1,'cherry',4]]
l2 = [[1,'apple',3],[1,'plums',4],[1,'orange',3],[1,'apple',4]]
output = []
for e in l2:
if not e[1] in [f[1] for f in l1]: # search by matching fruit
output.append(e)
print(output)
Output
[[1, 'plums', 4], [1, 'orange', 3]]
You can store all the unique elements from list1 in a new list, then check for list2 if that element exists in the new list. Something like:
newlist = []
for item in l1:
if item[1] not in newlist:
newlist.append(item)
output = []
for item in l2:
if item[1] not in newlist:
output.append(item)
print(output)
This is slightly inefficient but really straightforward to understand.

Trying to separate items in list by character but output returns multiple times

I am trying to separate items in a list by character, and this is done but whenever i run the code it separates the items but shows them separated multiple times. How can I fix this?
I've already tried using range in a for function, but that hasn't worked. The only thing that gives an output is using
for character in x
My code:
def rle():
askq = int(input("How many lines of RLE compressed data do you want to enter?"))
if askq < 2:
print("You must enter at least 2 lines of RLE compressed data.")
rle()
print("Please enter your RLE compressed data one line at a time")
lines = []
for i in range (0, askq):
i = input("Which lines would you like to convert?")
lines.append(i)
num=0
lines_input = [1,num]
lines2 = []
x = []
for i in range(0,askq):
num+=1
if num in lines_input:
x.append(lines[i])
for x in lines:
for character in x:
lines2.append(character)
print(lines2)
rle()
I expect the output of
lines2
to be
["0","1","d","6","1"," ","0","1","b"]
but instead i get
['0', '1', 'd', '6', '1', ' ', '0', '1', 'b', '0', '1', 'd', '6', '1', ' ', '0', '1', 'b', '0', '1', 'd', '6', '1', ' ', '0', '1', 'b']
['0', '1', 'd', '6', '1', ' ', '0', '1', 'b', '0', '1', 'd', '6', '1', ' ', '0', '1', 'b', '0', '1', 'd', '6', '1', ' ', '0', '1', 'b', '0', '1', 'd', '6', '1', ' ', '0', '1', 'b', '0', '1', 'd', '6', '1', ' ', '0', '1', 'b', '0', '1', 'd', '6', '1', ' ', '0', '1', 'b']
['0', '1', 'd', '6', '1', ' ', '0', '1', 'b', '0', '1', 'd', '6', '1', ' ', '0', '1', 'b', '0', '1', 'd', '6', '1', ' ', '0', '1', 'b', '0', '1', 'd', '6', '1', ' ', '0', '1', 'b', '0', '1', 'd', '6', '1', ' ', '0', '1', 'b', '0', '1', 'd', '6', '1', ' ', '0', '1', 'b', '0', '1', 'd', '6', '1', ' ', '0', '1', 'b', '0', '1', 'd', '6', '1', ' ', '0', '1', 'b', '0', '1', 'd', '6', '1', ' ', '0', '1', 'b']
Try this update
def rle():
askq = int(input("How many lines of RLE compressed data do you want to enter?"))
if askq < 2:
print("You must enter at least 2 lines of RLE compressed data.")
rle()
print("Please enter your RLE compressed data one line at a time")
lines = []
for i in range (0, askq):
i = input("Which lines would you like to convert?")
lines.append(i)
new_list = []
for i in lines:
new_list.extend(list(i))
print(new_list)
rle()

How can a return statement of a Python function keep strings in the same line like print(argument, end='')?

I am fresh off the coding boat and I am attempting to have the return values of a python function all print on one line. I know to use print(argument, en= ''), although I cannot include a print function in the return of a defined function.
Ultimately I am trying to get each first item of a list in a list, then the second and so on to print the design turned 90 degrees. I am first getting each list in a for loop then getting each index from there and printing in a second for loop.
With the code the way I have it now, I get the result I need, but there is "None" at the end of each line because I have a print function in a function instead of a "return" so I can have each index value printed on one line per list. I am curious about how to have the values displayed on one line without using the end argument of a print function in a function return. And I would always love to see a better/faster way to achieve this result.
..OO.OO..
.OOOOOOO.
.OOOOOOO.
..OOOOO..
...OOO...
....O....
Thank you!
grid = [['.', '.', '.', '.', '.', '.',],
['.', '0', '0', '.', '.', '.',],
['0', '0', '0', '0', '.', '.',],
['0', '0', '0', '0', '0', '.',],
['.', '0', '0', '0', '0', '0',],
['0', '0', '0', '0', '0', '.',],
['0', '0', '0', '0', '.', '.',],
['.', '0', '0', '.', '.', '.',],
['.', '.', '.', '.', '.', '.',]]
xLength = len(grid[0])-1
yLength = len(grid)-1
listX = list(range(0, xLength))
listY = list(range(0, yLength))
def listGrid(y = 0):
for x in grid:
print(x[y], end = '')
for num in listX:
print(listGrid(num))
You need to return a value from the function - if a function does not return anythin, it returns None implicitly. Your code prints the "data" inside the function and you print the return of the function by
print(listGrid(num)) # prints None
Print the results of your function outside, using end="" is an option:
grid = [['.', '.', '.', '.', '.', '.',],
['.', '0', '0', '.', '.', '.',],
['0', '0', '0', '0', '.', '.',],
['0', '0', '0', '0', '0', '.',],
['.', '0', '0', '0', '0', '0',],
['0', '0', '0', '0', '0', '.',],
['0', '0', '0', '0', '.', '.',],
['.', '0', '0', '.', '.', '.',],
['.', '.', '.', '.', '.', '.',]]
xLength = len(grid[0]) # fix, do not subtract 1 - range is upper border exclusive
yLength = len(grid)-1
listX = list(range(0, xLength))
listY = list(range(0, yLength))
def listGrid(y = 0):
return [x[y] for x in grid] # return a list
for num in listX:
for r in listGrid(num):
print(r, end="")
print()
Or you leverate zip() to make columns from your rows and print them:
# directly operates on your data - you do not need anything of your code beside
# the grid definition
for c in zip(*grid):
print(''.join(c))
Output:
..00.00..
.0000000.
.0000000.
..00000..
...000...
....0....

Appending a sublist to another list in python

with open('LBP_for_paper.csv','r') as csvDataFile:
datarows = csv.reader(csvDataFile, delimiter=',', quotechar='|')
nofinding=[]
rawrow=[]
for row in datarows:
if row[1]=='No Finding' and row[2]=='1':
rawrow = list((row[0]+","+row[1]+","+row[2]+","+row[17]+","+row[18]))
nofinding.append(rawrow)
print(nofinding[:2])
I am reading datarows from a csv file and want to create a customized nested list based on certain columns. I want that
list((row[0]+","+row[1]+","+row[2]+","+row[17]+","+row[18]))
shall return a list like
['00030805_000.png,No Finding,1,34777,69373']
which is stored in rawrow and then append to a bigger list i.e. nofinding but i am getting output as
[['0', '0', '0', '3', '0', '8', '0', '5', '', '0', '0', '0', '.',
'p', 'n', 'g', ',', 'N', 'o', ' ', 'F', 'i', 'n', 'd', 'i', 'n', 'g',
',', '1', ',', '3', '4', '7', '7', '7', ',', '6', '9', '3', '7', '3'],
['0', '0', '0', '3', '0', '8', '0', '4', '', '0', '0', '0', '.', 'p',
'n', 'g', ',', 'N', 'o', ' ', 'F', 'i', 'n', 'd', 'i', 'n', 'g', ',',
'1', ',', '3', '5', '4', '0', '5', ',', '6', '3', '0', '8', '8']]
Desired output
[ ['00030805_000.png,No Finding,1,34777,69373'], ['00030804_000.png,No
Finding,1,35405,63088'] ]
Thank you
Your issue is that rawrow = list((row[0]+","+row[1]+","+row[2]+","+row[17]+","+row[18])) is turning the string in to a list of characters
if you want to leave this as a comma delimited string replace that line with the following:
rawrow = row[0]+","+row[1]+","+row[2]+","+row[17]+","+row[18]
or more cleanly:
rawrow = ",".join([row[row_index] for row_index in [0, 1, 2, 17, 18]])
I am curious though why you want:
[ ['00030805_000.png,No Finding,1,34777,69373'], ['00030804_000.png,No Finding,1,35405,63088'] ]
Instead of this:
[ ['00030805_000.png','No Finding',1,34777,69373], ['00030804_000.png','No Finding',1,35405,63088] ]
which you could achieve with the following:
rawrow = []
for row_index in [0, 1, 2, 17, 18]:
rawrow.append(row[row_index].split(","))
or in one line:
rawrow = [row[row_index].split(",") for row_index in [0, 1, 2, 17, 18]]
Furthermore, your whole code could be consolidated as follows:
with open('LBP_for_paper.csv','r') as csvDataFile:
datarows = csv.reader(csvDataFile, delimiter=',', quotechar='|')
nofinding = [",".join([row[row_index] for row_index in [0, 1, 2, 17, 18]]) for row in datarows if row[1]=='No Finding' and row[2]=='1']
print(nofinding[:2])
with open('LBP_for_paper.csv','r') as csvDataFile:
datarows = csv.reader(csvDataFile, delimiter=',', quotechar='|')
rawrow = []
nofindings=[]
for row in datarows:
if row[1]=='No Finding' and row[2]=='1':
rawrow = [''.join(row[row_index]) for row_index in [0, 1, 2, 17, 18] ]
nofindings.append(rawrow)
print(nofindings[:3])
Solved my issues.

Resources