I am new in python. I have a two dimensional list in django. Now I want to check if given text is in list or not. But its not working. Here is my code:
newmessage = 'Bye'
stockWords = [
['hello', 'hi', 'hey', 'greetings'],
['Bye', 'Goodbye']
]
for i in range(0, len(stockWords)):
if newmessage.lower() in stockWords[i]:
return HttpResponse('Found')
else:
return HttpResponse('Not Found')
The problem is it works only for first element of list, the second one is not working.
What am I doing wrong? Any suggestion?
Update: your code checks for .lower() string, which isn't in any of the lists. ('bye' and 'Bye' are two different objects) I've tested my code without it, and it works:
>>> for i in stockWords:
if newmessage in i:
print 'found'
found
In order for this to work you need to lowercase all your strings in the list.
stocksLower = [stock.lower() for in_list in stockWords for stock in in_list]
Note it will create a single list, not list of lists.
You don't need to iterate over range when you have a sequence (list of lists in your case). You can iterate straight over it
for i in stockWords:
if newmessage.lower() in i:
return HttpResponse('Found')
else:
return HttpResponse('Not Found')
i now contains one element from stockWords list and test for containment.
Your original code was iterating over the len of stockWords which s 2. So it didn't check the inner lists.
you can try it, generate flatten one level lower list, and find in it
import itertools
stockWords = [
['hello', 'hi', 'hey', 'greetings'],
['Bye', 'Goodbye']
]
stock = itertools.chain.from_iterable(stockWords)
stock_lower = [x.lower() for x in stock]
newmessage = 'Bye'
if newmessage.lower() in stock_lower:
return HttpResponse('Found')
else:
return HttpResponse('Not Found')
newmessage = 'Bye'
stockWords = [
['hello', 'hi', 'hey', 'greetings'],
['Bye', 'Goodbye']
]
for i in range(0, len(stockWords)):
if newmessage.lower() in [str(x).lower() for x in stockWords[i]]:
print( 'Found')
else:
print( 'Not Found')
Your stockWords is a nested list when you are using for loop its taking only 2 elements (2 list), you can flat the nested list or change looping logic so that you can traverse in nested loops too
Try this(without flat):
newmessage = 'Bye'
stockWords = [['hello', 'hi', 'hey', 'greetings'],['Bye', 'Goodbye']]
for r in stockWords:
for c in r:
if newmessage.lower() == c.lower():
print("Found")
else:
print ('Not found')
If not mistaken #tisuchi is trying to create a function (wanted to return something) but not defining.
You can also use list comprehension. I have modified answer #WBM
found = False
for i in stockWords:
for j in i:
if newmessage.lower() not in j:
continue
else:
found = True
break
response = HttpResponse('Found') if found else HttpResponse('Not Found')
Related
I have a list of list elements that I'm modifying. And after that modification I want to put them into a list that have the same structure as the original one:
list_data_type = [
[['void1']], [['uint8']], [['uint8'], ['uint32']], [['void2']], [['void3']], [['void4']], [['void5']]
]
Firstly I check for elements that have more than one element. So in this case that would be element with index number = 2. Then I change it into a string, strip it from brackets [] and " " marks and convert it to a list. Then I take other elements and do the same thing. After conversion I want to create a new list with those elements, but without unnecessary symbols. So my desired output would look like this:
list_data_converted = [
['void1'], ['uint8'], ['uint8', 'uint32'], ['void2'], ['void3'], ['void4'], ['void5']
]
Conversion works and I can print out elements, but I have a problem with appending them to a list. My code saves only last value from original list:
def Convert(string):
li = list(string.split(" "))
return li
for element in list_data_type:
if type(element) == list:
print("element is a:", element, type(element))
if len(element) > 1:
id_of_el = list_data_type.index(element)
el_str = str(element).replace('[', '').replace("'", '').replace("'", '').replace(']', '').replace(',', '')
el_con = Convert(el_str)
elif len(element <= 1):
elements_w_1_el = element
list_el = []
for i in range(len(elements_w_1_el)):
el_str_2 = str(element).replace('[', '').replace("'", '').replace("'", '').replace(']', '').replace(',', '')
list_el.append(elements_w_1_el[i])
And my out instead looking like "list_data_converted", has only one element - ['void5']. How do I fix that?
Converting a list to a string to flatten it is a very... cumbersome approach.
Try simple list-comprehension:
list_data_type = [[v[0] for v in l] for l in list_data_type]
Type casting the list into a string and then replacing the characters and then again converting the string into list might be bad way to achieve what you're doing.
Try this :
def flatten(lst):
if lst == []:
return lst
if isinstance(lst[0], list):
return flatten(lst[0]) + flatten(lst[1:])
return lst[:1] + flatten(lst[1:])
list_data_converted = [flatten(element) for element in list_data_type]
This actually flattens any list item inside list_data_type and keep them in a single list. This should work with any depth of list inside list.
Output print(list_data_converted) would give the following :
[
['void1'], ['uint8'], ['uint8', 'uint32'], ['void2'], ['void3'], ['void4'], ['void5']
]
Is it possible to take out text in pairs of brackets out of a string into a list, with the non-bracketed text in another list, with both lists being nested in the same list? This is what I mean:
"hello{ok}why{uhh}so" --> [["hello","why","so"],["ok","uhh"]]
As per the sample you shared, this is quite easy with re modules. However, if your text is huge, you will have to think about improvising this solution. Using re, you can do something like below
import re
raw_text = "hello{ok}why{uhh}so"
result = [re.split(r"{[A-Za-z]*}", raw_text),re.findall(r"{([A-Za-z]*)}",raw_text)]
print(result)
produces a result
[['hello', 'why', 'so'], ['ok', 'uhh']]
Following piece of code may help you
input_str = "hello{ok}why{uhh}so"
list1, parsed_parentheses = [], []
for index in range(len(input_str)):
if input_str[index] == "{":
parsed_parentheses.append(input_str[index])
substr = ""
continue
else:
if parsed_parentheses == []:
continue
if input_str[index] == "}":
parsed_parentheses.append(input_str[index])
list1.append(substr)
if "{" == parsed_parentheses[-1]:
substr += input_str[index]
input_str = input_str.replace("{", "-").replace('}', "-").split('-')
list2 = list(set(input_str) - set(list1))
result = [list2, list1]
It produces the following result
[['hello', 'why', 'so'], ['ok', 'uhh']]
I am defining a list of dictionaries and I need to print only the one dictionary based on my input in check_if_in_list
first_list = {'a':'1','b':'2'}
second_list = {'a':'10','b':'20'}
all_lists =[first_list, second_list]
for element in all_lists:
check_if_in_list = input('give a valid number')
if check_if_in_list = (item['a'] for item in all_lists):
I need something like that
print(element where item['a]=check_if_in_list)
for example if I enter '1' in input in check_if_in_list, the print should be :
{'a':'1','b':'2'}
This will give you the output you require. If I have interpreted your requirement correctly, it's actually much simpler than the (I assume) semi-pseudocode that you posted.
first_dict = {'a':'1','b':'2'}
second_dict = {'a':'10','b':'20'}
all_dicts =[first_dict, second_dict]
check_if_in_list = input('give a valid number')
for element in all_lists:
if check_if_in_list == element['a']:
print(element)
If you need it as a comprehension, this would work:
print(*[element for element in all_lists if element['a'] == check_if_in_list])
This utilises star-unpacking to return the values of the list for printing, which should either be a dictionary or nothing in your case. (Thanks to #HampusLarsson for the reminder).
If your original code, you're looping over all_lists twice, which is unnecessary.
I'm writing some code:
for b in result:
#if re.match('[V]\W\d\W\D+\.*\D+\W\d+\W+', b) not in str(b):
if 'FillLevel[' not in str(b):
new_list.append(b)
#elif 'CycleMAX[' not in str(b):
# new_list.append(b)
#elif 'CycleMIN[' not in str(b):
# new_list.append(b)
#elif 'CycleAvg[' not in str(b):
# new_list.append(b)
And their work only when i have one condition (if).
How to change this code to work with few condition ?
result is an array, for example result[5] == ['V', '4', 'FillLevel[64]', "S7:[CPUA]DB1610', 'INT126", '2', 'CPUA.DB1610.126,I;RW', 'RW', '0', "0']"]
Maybe like this:
for b in result:
for entry in ['FillLevel[', 'CycleMAX[', ...]:
if entry not in str(b):
new_list.append(b)
Or, if #TigerhawkT3 has commented, the more shorter, pythonic and unreadable way would be:
for b in result:
if any(item not in str(b) for item in ('FillLevel[', 'CycleMAX[', ...)):
new_list.append(b)
Hope this helps!
What do you actually intend to do? Your example code would filter out only the lists that contain all of the words 'FillLevel[', 'CycleMAX[', 'CycleMIN[', etc. altogether. So only lists like this would get removed: ['V', '4', 'FillLevel[64]', 'CycleMAX[', 'CycleMIN[', ...].
TigerhawkT3's code works correctly if that's what you want.
For linusg's first example you'd have to add a break after the new_list.append(b) line, otherwise it appends the same lists several times.
Did you maybe intend to remove all the lists that contain any of these words not all? Then try something like this (similar to the other answers):
words = ('FillLevel[', 'CycleMAX[', 'CycleMIN[') # etc.
for b in results:
if not any(word in str(b) for word in words):
new_list.append(b)
Or:
for b in results:
for word in words:
if word in str(b):
break
else: # This else clause is executed only if no break occurs.
new_list.append(b)
Or as a list comprehension:
new_list = [b for b in results if not any(word in str(b) for word in words)]
Let's say that you have a string array 'x', containing very long strings, and you want to search for the following substring: "string.str", within each string in array x.
In the vast majority of the elements of x, the substring in question will be in the array element. However, maybe once or twice, it won't be. If it's not, then...
1) is there a way to just ignore the case and then move onto the next element of x, by using an if statement?
2) is there a way to do it without an if statement, in the case where you have many different substrings that you're looking for in any particular element of x, where you might potentially end up writing tons of if statements?
You want the try and except block. Here is a simplified example:
a = 'hello'
try:
print a[6:]
except:
pass
Expanded example:
a = ['hello', 'hi', 'hey', 'nice']
for i in a:
try:
print i[3:]
except:
pass
lo
e
You can use list comprehension to filter the list concisely:
Filter by length:
a_list = ["1234", "12345", "123456", "123"]
print [elem[3:] for elem in a_list if len(elem) > 3]
>>> ['4', '45', '456']
Filter by substring:
a_list = ["1234", "12345", "123456", "123"]
a_substring = "456"
print [elem for elem in a_list if a_substring in elem]
>>> ['123456']
Filter by multiple substrings (Checks if all the substrings are in the element by comparing the filtered array size and the number of substrings):
a_list = ["1234", "12345", "123456", "123", "56", "23"]
substrings = ["56","23"]
print [elem for elem in a_list if\
len(filter(lambda x: x in elem, substrings)) == len(substrings)]
>>> ['123456']
Well, if I understand what you wrote, you can use the continue keyword to jump to the next element in the array.
elements = ["Victor", "Victor123", "Abcdefgh", "123456", "1234"]
astring = "Victor"
for element in elements:
if astring in element:
# do stuff
else:
continue # this is useless, but do what you want, buy without it the code works fine too.
Sorry for my English.
Use any() to see if any of the substrings are in an item of x. any() will consume a generator expression and it exhibits short circuit beavior - it will return True with the first expression that evaluates to True and stop consuming the generator.
>>> substrings = ['list', 'of', 'sub', 'strings']
>>> x = ['list one', 'twofer', 'foo sub', 'two dollar pints', 'yard of hoppy poppy']
>>> for item in x:
if any(sub in item.split() for sub in substrings):
print item
list one
foo sub
yard of hoppy poppy
>>>