I want to print the shortest strings in a list.
for example the output for:
names=["Hans", "Anna", "Vladimir", "Michael", "Ed", "Susan", "Janice", "Jo"]
will be
"Ed", "Jo"
The output for
names=["Hans", "Anna", "Vladimir", "Michael", "Ed", "Susan", "Janice", "Jo", "Al"]
will be:
"Ed", "Jo", "Al"
[x for x in names if x==min(names, key=len)]
will get only one of them, but will not help in cases where there is more than one.
Pass len as key to the min method and get the length of the smallest string and then use list comprehension as:
names=["Hans", "Anna", "Vladimir", "Michael", "Ed", "Susan", "Janice", "Jo"]
smallest_len = len(min(names, key=len))
smallest = [name for name in names if len(name) == smallest_len]
First find the length of the shortest string:
shortest = min(map(len, names))
Now just find all strings with that length:
print([name for name in names if len(name) == shortest])
names = ["Hans", "Anna", "Vladimir", "Michael", "Ed", "Susan", "Janice", "Jo"]
smallest_len = len(min(names, key=len))
shorts = []
for name in names:
if len(name) == smallest_len:
shorts.append(name)
print(shorts)
Based on the question, my guess is that you're a Python beginner, so I really don't want to introduce you to advanced pythonic concepts.
Using no advanced concepts of the language, it's straight forward:
names = ["Hans", "Anna", "Vladimir", "Michael", "Ed", "Susan", "Janice", "Jo"]
def get_all_shortest_strings(strings: list) -> list: # Accept a list of strings and return a list of strings as well
shortest_strings = [] # Start with an empty list. This is the identity element for list addition
shortest_length = 9999999999999999 # Start with a huge number. This is the identity element for the minimum() function
for string in strings: # Go through all strings.
if len(string) == shortest_length: # Found one of the same length?
shortest_strings.append(string) # Add it!
if len(string) < shortest_length: # Found a shorter one?
shortest_strings = [] # Clear all longer ones
shortest_strings.append(string) # Add the one we just found
shortest_length = len(string) # remember the length
return shortest_strings
assert ["Ed", "Jo"] == get_all_shortest_strings(names)
You may want to read about the identity element. Basically it says that this element will not change the result of a given operation.
You may also not have seen assert before. You can use asserts for checking if your code works, without the need of printing something.
To loop only once, and call len on each item once:
names = [
"Hans", "Anna", "Vladimir", "Michael", "Ed", "Susan", "Janice", "Jo", "Al"
]
def find_shortests(names: list):
result = []
shortest = float("inf")
for x in names:
n = len(x)
if n > shortest:
continue
if n < shortest:
result.clear()
shortest = n
result.append(x)
return result
print(find_shortests(names))
# ['Ed', 'Jo', 'Al']
Related
I'm trying to remove the similar duplicates from my list.
Here is my code:
l = ["shirt", "shirt", "shirt len", "pant", "pant cotton", "len pant", "watch"]
res = [*set(l)]
print(res)
This will Remove only shirt word which is actually duplicate, but I'm looking to remove the similar words to remove like shirt Len,pant cotton,Len pant. Like that.
Expecting Output as
Shirt,pant,watch
It sounds like you want to check if the single-word strings are in any other string, and if so remove them as a duplicate. I would go about it this way:
Separate the list into single-word strings and any other string.
For each longer string, check if any of the single-word strings is contained in it.
If so, remove it. Otherwise, add it to the result.
Finally, add all the single-word strings to the result.
l = ["shirt", "shirt", "shirt len", "pant", "pant cotton", "len pant", "watch"]
single, longer = set(), set()
for s in l:
if len(s.split()) == 1:
single.add(s)
else:
longer.add(s)
res = set()
for s in longer:
if not any(word in s for word in single):
res.add(s)
res |= single
print(res)
This example will give:
{'shirt', 'watch', 'pant'}
You can try something like below:
by selecting single word element from list and then apply set
lst = ["shirt", "shirt", "shirt len", "pant cotton", "len pant", "watch"]
set([ls for ls in lst if ' 'not in ls])
#Output {'pant', 'shirt', 'watch'}
note if your input will ["shirt", "shirt", "shirt len", "pant cotton", "len pant", "watch"] then output will be {'shirt', 'watch'}
and if still would like to add pant, cotton then you can try
set(sum([ls.split(' ') for ls in lst], []))
#output {'cotton', 'len', 'pant', 'shirt', 'watch'}
and later filter out word by conditions as per your requirements
I have the following problem. I want to compare two lists with dictionaries and find matches.
Schema List A:
[
{
authorID: string,
articleID: string
}
]
Schema List B:
[
{
authorID: string,
firstName: string,
lastName: string
}
]
The length of the list A is 1653 and the list B is 1344 long.
This is my code with which I tried to compare the lists and resave the matches.
def unitedListArticleAuthor(listA, listB):
new_list = []
for article in listA:
for author in listB:
if article["authorID"] == author["authorID"]:
new_list.append({
"articleID": article["articleID"],
"authorID": article["authorID"],
"firstName": author["firstName"],
"lastName": author["lastName"],
})
Now the length of the new list is 1667. That means somewhere a mistake must have happened, because the list A is the biggest and only has to be matched with the list B. Only the author ID's should be matched to add the name of the author to each article.
What is my mistake?
As Sayse said, it is likely that there are multiple instances of the same authorID.
You seem really sure that this is not the case, but try adding a break statement like this:
def unitedListArticleAuthor(listA, listB):
new_list = []
for article in listA:
for author in listB:
if article["authorID"] == author["authorID"]:
new_list.append({
"articleID": article["articleID"],
"authorID": article["authorID"],
"firstName": author["firstName"],
"lastName": author["lastName"],
})
break
in my list I want the function to return only the maximum values within the list
my_list = ["and", "the", "plus", "from", "i" , "09"]
How can I get the output to be the maximum values ("plus", "from")
I did something like that, and I could not continue ...
my_list = ["and", "the", "plus", "from", "i" , "09"]
list1 = str(my_list)
list2 = list1.split(',')
for i in list2:
if len(i) == max(len(i)):
print(i)
Thanks for the help
def myFunction(words: list):
output = []
for word in sorted(words, key=len, reverse=True):
maxLen = len(sorted(words, key=len, reverse=True)[0])
if(len(word) < maxLen):
break
output.append(word)
return {
"words": output,
"length": maxLen
}
It takes the words list and sorts it from greatest to least length, then sets the maxLen variable to the length of the first thing in that list. Then, it looks to see if the length of the word the for loop is less than maxLen, and if it is, it stops the loop.
If you would like to get the lenght of longest string in list, you can use the shorhand version foor lop like max([len(item) for item in my_list]). but as far as I understood you would like to get the the string even if there are strings with same length you can try this:
def longest_items(my_list):
max_len = 0
items = []
for item in my_list:
if len(item) > max_len:
max_len = len(item)
items.clear()
items.append(item)
elif len(item) == max_len:
items.append(item)
return tuple(items)
This function will return longest string or strings in a tuple.
You can quickly use some list comprehension:
>>> my_list = ["and", "the", "plus", "from", "i" , "09"]
>>> lengths = [len(s) for s in my_list]
>>> max_lengths = [s for s in my_list if len(s) == max(lengths)]
>>> max_lengths
["plus", "from"]
The list in lengths stores the length of each string in my_list. Then, by using the max() function, we can quickly obtaining the maximum value in lengths, which corresponds to the maximum length of a string. Finally, we re-iterate over my_list and compare each string value to max(lengths), checking if each string is the maximum length.
Note that, if desired, this all can be condensed into one list comprehension:
>>> max_lengths = [i for i in my_list if len(i) == max([len(s) for s in my_list])]
>>> max_lengths
["plus", "from"]
my_list = ["and", "the", "plus", "from", "i", "09"]
length = 0
arr = []
for i in my_list:
if len(i) > length:
length = len(i)
arr = []
if len(i) == length:
arr.append(i)
length = len(i)
print(arr)
list2 = list1.split(',')
split is a string function, it turns a string into a list. Like "john, tim, and paul" would turn into ["john", " tim", " and paul"]
max takes an iterator and returns the highest value. you did max(len(i)) ... len(i) is just going to return an integer, so you did max(6). Instead, you want to make a list of the lengths. max([len(x) for x in list1]) would give you the length of the longest item in list1.
I have a dictionary that contains strings as keys and lists as values.
I'd like to remove all list elements that contain the strings "food", "staging", "msatl" and "azeus". I have the below code already, but am having a hard time applying the logic I have in filterIP to the rest of the strings I have.
def filterIP(fullList):
regexIP = re.compile(r'\d{1,3}.\d{1,3}.\d{1,3}.\d{1,3}$')
return filter(lambda i: not regexIP.search(i), fullList)
groups = {key : [domain.replace('fake.com', 'env.fake.com')
for domain in filterIP(list(set(items)))]
for (key, items) in groups.iteritems() }
for key, value in groups.iteritems():
value.sort()
meta = { "_meta" : { "hostvars" : hostvars } }
groups.update(meta)
print(self.json_format_dict(groups, pretty=True))
Example of current output
"role_thumper": [
"thumper-msatl1-prod-1.env.fake.com",
"thumper-msatl1-prod-2.env.fake.com",
"thumper-rwva1-prod-1.env.fake.com",
"thumper-rwva1-prod-2.env.fake.com",
"thumper-rwva1-prod-3.env.fake.com",
"thumper-rwva1-prod-4.env.fake.com",
"thumper-rwva1-prod-5.env.fake.com",
"thumper-rwva1-prod-6.env.fake.com",
"thumper-staging-1.env.fake.com"
],
"role_thumper_mongo": [
"thumper-mongo-staging-1.env.fake.com",
"thumper-mongo-staging-2.env.fake.com",
"thumpermongo-rwva1-staging-1.env.fake.com",
"thumpermongo-rwva1-staging-2.env.fake.com"
],
"role_thumper_mongo_arb": [
"thumper-mongo-arb-staging-1.env.fake.com",
"thumpermongo-arb-rwva1-staging-1.env.fake.com"
],
A list comprehension is what you're after
x= ["a", "b", "aa", "aba"]
x_filtered = [i for i in x if "a" not in i]
print(x_filtered)
>>> ['b']
This is just shorthand for a for loop.
x_filtered = []
for i in x:
if "a" not in i:
x_filtered.append(i)
A simple way to accomplish your task would be to iterate over each lists in the dictionary. Create new lists based upon your criteria, and assign the new lists to the same keys but in a new dictionary. Here is how that would look like in code:
def filter_words(groups, words):
d = {}
for key, domains in groups.iteritems():
new_domains = []
for domain in domains:
if not any(word in domain for word in words):
new_domains.append(domain)
d[key] = new_domains
return d
And you would call it like so:
groups = filter_words(groups, {"food", "staging", "msatl" and "azeus"})
The "meat" of the code above is the second for loop:
for domain in domains:
if not any(word in domain for word in words):
new_domains.append(domain)
This code goes over each string in the current key's list, and filters out all invalid strings according to a list of invalid words.
If I understand you correctly, this might help.
Set up an exclude list:
exclude= ["food", "staging", "msatl", "azeus"]
Test list ( I couldn't really find instances in your examples)
test= ["food", "staging", "msatl", "azeus", "a", "bstaging"]
Run list comprehension (the name of iterators don't matter, you can pick more appropriate ones)
result= [i for i in test if not any([e for e in exclude if e in i])]
result
['a']
The answer above by #Julian gives a good explanation of what list comprehensions do. This uses two of them, the any part is True if there is any match in the exclude list.
Hope this helps.
I was wondering how would you find the index of a element in a list if you only had part of it. For example
list = ["this", "is", "an", "example", "for", "python"]
how would you find it if you only had "pyt" and needed the index for python???
Straightforward for loop:
def find_starts(val, my_list):
for i, v in my_list:
if v.startswith(val):
return i
(If there is no match then this returns None.) This could be made neater with a list comprehension: see this related question for more details.
As the question is not 100% clear i assume you want to find all items that include the specified string.
alist = ["this", "is", "an", "example", "for", "python"]
val = 'is'
def find_in_list(alist, val):
res = []
for e, v in enumerate(alist):
if val in v:
res.append(e)
return res
find_in_list(alist, val)
You have to work with a solution that work when some element are similar (for example ["foo", "asd", "foobar"] and you have "foo" what would be detected as a correct element?)
The given function will return a list of indexes, which were identified as a correct element.
def find(foo, list):
#Find similar elements
similarElements = [e for e in list if foo in e]
#Find their indexes
indexes = [similarElements.index(i) for i in similarElements]
return indexes
This solution isn't the fastest way, but an easy and understandable.
>>> list = ["this", "is", "an", "example", "for", "python"]
>>> word = "python"
>>> y = [i for i,j in enumerate(list) if j == word]
>>> y
[5]
However, this is for the whole word, try this aswell.
>>> word = "py"
>>> for w in list:
... if word in w:
... sus.append(w)
... print(sus)
...
['python']