Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed last month.
Improve this question
I have a first list, containing string lists and a second list containing strings. I want that when a string from the first list is found in the second, the string from the second is returned and the search resumes at the next string from the first list.
list1 = [
['test', 'string'],
['hello', 'world']
['good', 'morning','everyone']]
list2 = [
['test is here'],
['hi everyone'],
['world of code']]
If list1[0][0] is in list2[0], then return list2[0] and go to list1[1] (don't want to test list1[0][1]).
I've tried nesting for loops inside other for loops with break and if conditions but can't get the solution.
If the length of lists is the same, the code should be something like this:
list1 = [
['test', 'string'],
['hello', 'world'],
['good', 'morning', 'everyone']]
list2 = [
['test is here'],
['hi everyone'],
['world of code']]
answer = []
for l1 in range(len(list1)):
for item in list1[l1]:
if item in str(list2[l1]):
answer.append(item)
break
print(*answer)
and output will be
test
Hope this helped! :D
First, here are some tips for solving problems like this in the future:
First, the format of your input data is pretty strange (in my opinion), so I'd really recommend trying to flatten everything out -- this may or may not be possible depending on the larger structure of your program, so if you can't actually do that, then no big deal. Something like:
list1 = [ ['test', 'string'], ['hello', 'world'], ['good', 'morning', 'everyone'] ]
list2 = ['test is here', 'hi everyone', 'world of code']
is already easier to work with from a data processing standpoint, and that's just from flattening list2.
Second, conceptually, you have to have two loops going on here -- the first is to iterate through list1 (so if you find a match in list2, you can return the match and move onto the next member of list1), and another to go through the individual elements of list1, since a string in list2 could match on any one of the strings from the inner lists in list1 (i.e. a string in list2 could be matched either by 'test' or 'string').
With that said, here's a (pretty inefficient) solution to your problem:
def check_long_str(long_strings, check_list):
for check in check_list: #iterate over individual strings in each inner list of list1
for long_string_item in long_strings: #look for a match in list2
long_string = long_string_item[0] #weird format
if check in long_string:
print('"{}" found "{}"'.format(check, long_string))
return long_string
return None
def check_for_strings(search_strings, long_strings):
toReturn = set()
for search_list in search_strings: #iterate over inner lists of list1
found_str = check_long_str(long_strings, search_list)
if found_str is not None:
toReturn.add(found_str)
return toReturn
print(check_for_strings(list1, list2))
Output:
"test" found "test is here"
"world" found "world of code"
"everyone" found "hi everyone"
set(['test is here', 'hi everyone', 'world of code'])
So there was an error in the code you gave. I found an issue in the code you gave. There is a typo which is a missing "," after one of the lists. This is right after the:
['hello', 'world']
list in list1.
Although there may be better ways to loop through a nested list, this is how I would do it.
list1 = [
['test', 'string'],
['hello', 'world'],
['good', 'morning', 'everyone']]
list2 = [
['test is here'],
['hi everyone'],
['world of code']]
found_words = []
for i in range(len(list1)):
for x in range(len(list1[i])):
for z in list2:
for y in z:
teststring = y.split()
for j in teststring:
if j in list1[i][x]:
found_words.append(j)
break
print(found_words)
Output:
['test', 'world', 'everyone']
Hopefully this helps!
Related
This question already has answers here:
Python - get the last element of each list in a list of lists
(5 answers)
Closed 2 years ago.
I have some nested lists. I want to extract the last occurring element within each sublist (eg 'bye' for the first sublist). I then want to add all these last occurring elements ('bye', 'bye', 'hello' and 'ciao') to a new list so that I can count them easily, and find out which is the most frequently occurring one ('bye).
The problem is that my code leaves me with an empty list. I've looked at Extracting first and last element from sublists in nested list and How to extract the last item from a list in a list of lists? (Python) and they're not exactly what I'm looking for.
Thanks for any help!
my_list = [['hello', 'bye', 'bye'], ['hello', 'bye', 'bye'], ['hello', 'hello', 'hello'], ['hello', 'bye', 'ciao']]
# Make a new list of all of the last elements in the sublists
new_list = []
for sublist in my_list:
for element in sublist:
if sublist.index(element) == -1:
new_list.append(element)
# MY OUTPUT
print(new_list)
[]
# EXPECTED OUTPUT
['bye', 'bye', 'hello', 'ciao']
# I would then use new_list to find out what the most common last element is:
most_common = max(set(new_list), key = new_list.count)
# Expected final output
print(most_common)
# 'bye'
You can call the last element of a list by calling the index -1, e.g. sublist[-1]. The following code should give you your expected result:
my_list = [['hello', 'bye', 'bye'], ['hello', 'bye', 'bye'], ['hello', 'hello', 'hello'], ['hello', 'bye', 'ciao']]
new_list = list()
for sublist in my_list:
new_list.append(sublist[-1])
print(new_list)
or as Risoko pointed out, you can do it in one line, so the code should look like
my_list = [['hello', 'bye', 'bye'], ['hello', 'bye', 'bye'], ['hello', 'hello', 'hello'], ['hello', 'bye', 'ciao']]
new_list = [sublist[-1] for sublist in my_list]
print(new_list)
You are looking for this:
for sublist in my_list:
new_list.append(sublist[-1])
The index -1 does not "really exist", it is a way to tell python to start counting from the end of the list. That is why you will not get a match when looking for -1 like you do it.
Additionally, you are walking over all the lists, which is not necessary, as you have "random access" by fetching the last item as you can see in my code.
There is even a more pythonic way to do this using list comprehensions:
new_list = [sublist[-1] for sublist in my_list]
Then you do not need any of those for loops.
output = [sublist[-1] for sublist in my_list]
I have a list:
lst = ['words in a list']
and I was hoping to split each one of these words in the string into their own separate indexes. So for example, it would look something like this:
lst = ['words','in','a','list']
I'm wondering if this is possible? I thought initially this would be just a simple lst.split() with a loop, but it seems like this is will throw an error.
Thanks for the help!
Use this:
print(lst[0].split())
If the list has more elements:
print([x for i in lst for x in i.split()])
Split only works for a string type. So you need to index the list item first and then split.
lst = lst[0].split()
Use this when you have a list of string or single string inside a list
lst = ['this is string1', 'this is string2', 'this is string3']
result =' '.join(lst).split()
print(result)
# output : ['this', 'is', 'string1', 'this', 'is', 'string2', 'this', 'is', 'string3']
Basically just looking if there is an easy way to reverse the list.
People were getting to confused with my original question.
This was the list: words = ['hey', 'hi', 'hello', 'hi']
How to reverse it (to a new list) and only add to new list if it is not already in it.
This snippet iterates through the list of words in reverse; and adds new unique entries to a new list.
words = ['hey', 'hi', 'hello', 'hi']
result = []
for word in reversed(words):
if word not in result:
result.append(word)
print(result)
Output
['hi', 'hello', 'hey']
Converting the first list to a set() ensures duplicates are removed. Then the set is converted to a reversely sorted list.
final_lst = sorted(set(words), reverse=True)
I'm looking for a way to remove duplicate entries from a Python list but with a twist; The final list has to be case sensitive with a preference of uppercase words.
For example, between cup and Cup I only need to keep Cup and not cup. Unlike other common solutions which suggest using lower() first, I'd prefer to maintain the string's case here and in particular I'd prefer keeping the one with the uppercase letter over the one which is lowercase..
Again, I am trying to turn this list:
[Hello, hello, world, world, poland, Poland]
into this:
[Hello, world, Poland]
How should I do that?
Thanks in advance.
This does not preserve the order of words, but it does produce a list of "unique" words with a preference for capitalized ones.
In [34]: words = ['Hello', 'hello', 'world', 'world', 'poland', 'Poland', ]
In [35]: wordset = set(words)
In [36]: [item for item in wordset if item.istitle() or item.title() not in wordset]
Out[36]: ['world', 'Poland', 'Hello']
If you wish to preserve the order as they appear in words, then you could use a collections.OrderedDict:
In [43]: wordset = collections.OrderedDict()
In [44]: wordset = collections.OrderedDict.fromkeys(words)
In [46]: [item for item in wordset if item.istitle() or item.title() not in wordset]
Out[46]: ['Hello', 'world', 'Poland']
Using set to track seen words:
def uniq(words):
seen = set()
for word in words:
l = word.lower() # Use `word.casefold()` if possible. (3.3+)
if l in seen:
continue
seen.add(l)
yield word
Usage:
>>> list(uniq(['Hello', 'hello', 'world', 'world', 'Poland', 'poland']))
['Hello', 'world', 'Poland']
UPDATE
Previous version does not take care of preference of uppercase over lowercase. In the updated version I used the min as #TheSoundDefense did.
import collections
def uniq(words):
seen = collections.OrderedDict() # Use {} if the order is not important.
for word in words:
l = word.lower() # Use `word.casefold()` if possible (3.3+)
seen[l] = min(word, seen.get(l, word))
return seen.values()
Since an uppercase letter is "smaller" than a lowercase letter in a comparison, I think you can do this:
orig_list = ["Hello", "hello", "world", "world", "Poland", "poland"]
unique_list = []
for word in orig_list:
for i in range(len(unique_list)):
if unique_list[i].lower() == word.lower():
unique_list[i] = min(word, unique_list[i])
break
else:
unique_list.append(word)
The min will have a preference for words with uppercase letters earlier on.
Some better answers here, but hopefully something simple, different and useful. This code satisfies the conditions of your test, sequential pairs of matching words, but would fail on anything more complicated; such as non-sequential pairs, non-pairs or non-strings. Anything more complicated and I'd take a different approach.
p1 = ['Hello', 'hello', 'world', 'world', 'Poland', 'poland']
p2 = ['hello', 'Hello', 'world', 'world', 'Poland', 'Poland']
def pref_upper(p):
q = []
a = 0
b = 1
for x in range(len(p) /2):
if p[a][0].isupper() and p[b][0].isupper():
q.append(p[a])
if p[a][0].isupper() and p[b][0].islower():
q.append(p[a])
if p[a][0].islower() and p[b][0].isupper():
q.append(p[b])
if p[a][0].islower() and p[b][0].islower():
q.append(p[b])
a +=2
b +=2
return q
print pref_upper(p1)
print pref_upper(p2)
Given a list of strings such as: ['Math is cool', 'eggs and bacon']
How would one swap words from one list item to the other to turn them into something like
['bacon is cool', 'eggs and Math']
I would post code if I had any but I really have no idea where to start with this. Thanks.
I'm using Python 3
Start by creating your lists.
text1 = 'Math is cool'
text2 = 'eggs and bacon'
mylist = []
mylist.append(text1.split())
mylist.append(text2.split()
print mylist
Output:
[['Math', 'is', 'cool'], ['eggs', 'and', 'bacon']]
Now that you have the lists, play with them. Use append() to add texts that the user enters, etc.
I think that you can see where to go from here.
You're not providing too much information as to your purpose in general (to say the least)... so the answer below refers only to the specific example given in your question, in order to help you get started:
list = ['Math is cool', 'eggs and bacon']
list0 = list[0].split(' ')
list1 = list[1].split(' ')
newList = [list1[-1]+' '+' '.join(list0[1:]), ' '.join(list1[:-1])+' '+list0[0]]
import random
def swap_words(s1, s2):
s1 = s1.split() # split string into words
s2 = s2.split()
w1 = random.randrange(len(s1)) # decide which words to swap
w2 = random.randrange(len(s2))
s1[w1], s2[w2] = s2[w2], s1[w1] # do swap
return " ".join(s1), " ".join(s2)
then swap_words('Math is cool', 'eggs and bacon') returns sentences like
('Math and cool', 'eggs is bacon')
('bacon is cool', 'eggs and Math')