python split list of strings, where index out of range - python-2.7

How do I return the second alpha character [if there is a second alpha character] of each item in a list? If there is not a second alpha character do nothing.
list = ["a b", "c d", "e"]
for item in list:
x = item.split()[1]
The last loop returns "IndexError: list index out of range" due to the fact that there is not a second item.

The error occurs because there's the item "e" which is split into one chunk (indexed with 0)Also, don't give variable reserved name as list.
For your simple case you may use the following:
l = ["a b", "c d", "e"]
result = [i.split()[1] if ' ' in i else i for i in l]
print(result)
The output:
['b', 'd', 'e']

This takes the item even if the length of it is 1(that is, it cannot be split)
x = [] #creates a list to hold the values
for item in list:
if(len(item)) == 1:
x.append(item)
else:
x.append(item.split()[1])
print(x)
This, ignores the item if it is not splittable:
x = [] #creates a list to hold the values.
for item in list:
if len(item) > 1:
x.append(item.split()[1])
print(x)

Related

return indexs from list of substring after matching with string

I have list of sub-strings , and I am checking if any of the substring is found in another string. any does return boolean.
>>> list=['oh' , 'mn' , 'nz' , 'ne']
>>> name='hstntxne'
>>> any(x in name for x in list)
True
>>> name='hstnzne'
>>> any(x in name for x in list)
True
I want to return index . for example first time it should be 3 and second time it should be 2 and 3.
Firstly, do not call your list list. list is a python data structure and you do not want to be overriding that name unless you have a specific reason for doing so.
You can easily achieve this with a list comprehension in one line.
substrings = ['oh' , 'mn' , 'nz' , 'ne']
name1='hstntxne'
name2='hstnzne'
[substrings.index(x) for x in substrings if x in name1]
This returns 3
[substrings.index(x) for x in substrings if x in name2]
This returns [2, 3]
In order to make this work with any list of substrings, and names put it in a function:
def getIndex(subs, name):
return [subs.index(x) for x in subs if x in name]
getIndex(substrings, name2) #example call
you can use inbuilt enumerate() function.
def get_index(name, lis=['oh' , 'mn' , 'nz' , 'ne']):
indx = []
for index, element in enumerate(lis):
if element in name:
indx.append(index)
return indx
Now get_index(name='hstnzne') will give [2, 3]
and get_index(name='hstntxne') will give [3]
import re
# Try and use regex to see if subpattern exists
l = ['oh', 'mn', 'nz', 'ne']
name='hstnzne'
match_indx = []
for i, sub_str in enumerate(l):
result = re.split(sub_str, name)
if (len(result)>1):
# We could split our string due to match, so add index of substring
match_indx.append(i)
print(match_indx)

Creating list of lists and skipping elements in Python

How can I create a list of list using [x for x in input] (where input is a list of strings) and skip elements if they satisfy certain condition? For example, this is the list of lists:
[['abc', 'def', 'ghi'], ['abc', 'd_f', '+hi'], ['_bc', 'def', 'ghi']]
and this should be the output -- with skipped elements containing either '_' or '+':
[['abc', 'def', 'ghi'], ['abc'], ['def', 'ghi']]
Thanks!
You'll need a sub-list comprehension:
[[item for item in sub if not any(char in item for char in '_+')] for sub in input]
which is a simplified version of:
result = []
for sub in input:
result.append([])
for item in sub:
should_add = True
for char in '_+':
if char in item:
should_add = False
break
if should_add:
result[-1].append(item)
Pretty similar to the other answer except tests if the string contains only alpha numeric characters as opposed to specifically '_' and '+'. Loops through each sub list then the strings in each sub list.
filtered = [[s for s in l if s.isalpha()] for l in lists]
print(filtered)
[['abc', 'def', 'ghi'], ['abc'], ['def', 'ghi']]
Another short version using a set:
stuff= [['abc', 'def', 'ghi'], ['abc', 'd_f', '+hi'], ['_bc', 'def', 'ghi']]
unwanted = {'+', '-'}
filtered = [[item for item in s if not set(s) & unwanted] for s in stuff]

first value in the list is equal to the first value in the other list. python2.7

so imagine I had a sublist
exList = [
['green', 'apple', 'NO'],
['red','apple','nO'],
['red','watermellon','no'],
['yellow','honeymellon','yes']
]
so I want to check if the first value in the list is equal to the first value in the other list.
so exlist is a sublist, it has 4 different list. So i want to check the first value in the first list and check if it's equal to any other value in the other list. So Green is the first value and green is not used in the other list so it should return False. But if green was used in the other lists it should return True.
for i in exList:
if i+1[1] == i-[1]:
print True
how can i do this?
So if I understand your request you want to check if the first value for the first list in exList exists in each of the remaining lists? If so you could use list comprehension as follows:
check = [True if (exList[0][0] in subList) else False for subList in exList[1:]]
or you can do this in a loop if you don't understand list comprehension:
check = []
checkItem = exList[0][0] #Pulls the value for the first item in the first list of exList
for i in range(1,len(exList)): #Starts at 1 to skip the first list in exList
check.append(checkItem in exList[i])
print check
And if you need to loop over each item in the first list to check:
for eachListItem in exList[0]:
print "Search Text: %s" % (eachListItem)
curCheck = [True if (eachListItem in subList) else False for subList in exList[1:]]
print "Search Results: %s" % (True in curCheck)
Note: None of this would account for spaces in a string or mismatched cases (I.E. NO and No are two different values and would return false. Similarly "No " and "No" are different)

Find unique items in a list using a passed value for range of the list (sublists)

I am trying to tie two different things together.
1. Find and print unique items in a list.
2. Pass a int value and print unique items in the first n items
I have two things that work, but not in conjunction, to split the list into sub-lists of n:
def find_uniques(3):
lista = ['a', 'a', 'b','c','d','c','e','d','e','f','f']
lists = [lista[x:x+n] for x in xrange(0, len(lista), n)]
print lists
[['a', 'a', 'b'], ['c', 'd', 'c'], ['e', 'd', 'e'], ['f', 'f']]
# 2nd part works on the whole list
print [a for a in lista if lista.count(a) == 1]
['b']
# How do I get the second part to work on the sub lists, and give me back unique chars from each sub list.
The output I am looking for:
[['b'],['d'], ['d']]
Usually it is easier to just split out these operations instead of merging, but here is a nested list comprehension.
lista = ['a', 'a', 'b','c','d','c','e','d','e','f','f']
n = 3
[[ item for item in sublist if sublist.count(item) == 1] for sublist in [ lista[x:x+n] for x in xrange(0, len(lista), n) ] ]
Personally, although it is longer, I prefer a more readable version like so:
def findunique(lista,n=3):
listoflists = [ lista[x:x+n] for x in xrange(0,len(lista),n) ]
results = []
for sublist in listoflists:
unique = [ item for item in sublist if sublist.count(item) == 1]
if unique:
results.append(unique)
return results
lista = ['a','a','b','c','d','c','e','d','e','f','f']
print findunique(lista,3)

Find and delete list elements if matching a string

I have a list of strings stringlist = ["elementOne" , "elementTwo" , "elementThree"] and I would like to search for elements that contain the "Two" string and delete that from the list so my list will become stringlist = ["elementOne" , "elementThree"]
I managed to print them but don't really know how to delete completely from the list using del because i don't know the index or by using stringlist.remove("elementTwo") because I don't know the exact string of the element containing "Two"
My code so far:
for x in stringlist:
if "Two" in x:
print(x)
Normally when we perform list comprehension, we build a new list and assign it the same name as the old list. Though this will get the desired result, but this will not remove the old list in place.
To make sure the reference remains the same, you must use this:
>>> stringlist[:] = [x for x in stringlist if "Two" not in x]
>>> stringlist
['elementOne', 'elementThree']
Advantages:
Since it is assigning to a list slice, it will replace the contents with the same Python list object, so the reference remains the same, thereby preventing some bugs if it is being referenced elsewhere.
If you do this below, you will lose the reference to the original list.
>>> stringlist = [x for x in stringlist if "Two" not in x]
>>> stringlist
['elementOne', 'elementThree']
So to preserve the reference, you build the list object and assign it the list slice.
To understand the subtle difference:
Let us take a list a1 containing some elements and assign list a2 equal to a1.
>>> a1 = [1,2,3,4]
>>> a2 = a1
Approach-1:
>>> a1 = [x for x in a1 if x<2]
>>> a1
[1]
>>> a2
[1,2,3,4]
Approach-2:
>>> a1[:] = [x for x in a1 if x<2]
>>> a1
[1]
>>> a2
[1]
Approach-2 actually replaces the contents of the original a1 list whereas Approach-1 does not.
You can use enumerate to get the index when you iterate over your list (but Note that this is not a pythonic and safe way to modify your list while iterating over it):
>>> for i,x in enumerate(stringlist):
... if "Two" in x:
... print(x)
... del stringlist[i]
...
elementTwo
>>> stringlist
['elementOne', 'elementThree']
But as a more elegant and pythonic way you can use a list comprehension to preserve the elements that doesn't contains Two :
>>> stringlist = [i for i in stringlist if not "Two" in i]
>>> stringlist
['elementOne', 'elementThree']
Doing this will help you
for i,x in enumerate(stringlist):
if "Two" in x:
del stringlist[i]
or
newList = []
for x in stringlist:
if "Two" in x:
continue
else
newList.append(x)
Using regex,
import re
txt = ["SpainTwo", "StringOne"]
for i in txt:
x = re.search(r"Two", i)
if x:
temp_list = temp_list + [x.string] if "temp_list" in locals() else [x.string]
print(temp_list)
gives
['SpainTwo']
print(list(filter(lambda x: "Two" not in x, ["elementOne" , "elementTwo" , "elementThree", "elementTwo"])))
Using lambda, if you are only looking to print.
if you want to check for multiple string and delete if detected from list of string use following method
List_of_string = [ "easyapplyone", "appliedtwotime", "approachednone", "seenthreetime", "oneseen", "twoapproached"]
q = ["one","three"]
List_of_string[:] = [x for x in List_of_string if any(xs not in x for xs in q)]
print(List_of_string)
output:[ "approachednone", "seenthreetime"]
Well this was pretty simple - sorry for all the trouble
for x in stringlist:
if "Two" in x:
stringlist.remove(x)