I'd like to replace the 'x-%' from the origin list with the values from 'anotherList' in loop.
As you can see, when looping through, only the last state is saved, because it replaces the standardList again.
What might be the best way to kind of 'save the state of every list' and then loop through it again?
Result should be:
result = ['I', 'just', 'try','to', 'acomplish', 'this','foo', 'list']
What I got so for:
originList = ['I', 'x-0', 'x-1','to', 'acomplish', 'x-2','foo', 'x-3']
anotherList = ['just','try','this','list']
for index in originList:
for num in range(0,4):
if 'x' in index:
result = str(originList).replace('x-%s'%(str(num)), anotherList[num])
print result
#['I', 'x-0', 'x-1', 'to', 'acomplish', 'x-2', 'foo', 'list'] <-- wrong :X
Thanks for any help because I can't figure it out at the moment
EDIT*
If there is a cleaner solution I would also appreciate to hear
This one avoids the creation of a new list
count = 0
for word in range(0, len(originList)):
if 'x-' in originList[word]:
originList[word] = anotherList[count]
count += 1
print originList
Here ya go!
>>> for original in originList:
if 'x' in original:
res.append(anotherList[int(original[-1])]) #grab the index
else:
res.append(original)
>>> res
['I', 'just', 'try', 'to', 'acomplish', 'this', 'foo', 'list']
>>>
Since the index of the value needed is in the items of originList, you can just use it, so no need for the extra loop. Hope this helps!
originList = ['I', 'x-0', 'x-1','to', 'acomplish', 'x-2','foo', 'x-3']
anotherList = ['just','try','this','list']
def change(L1, L2):
res = []
index = 0
for ele in L1:
if 'x-' in ele:
res.append(L2[index])
index += 1
else:
res += [ele]
return res
print(change(originList, anotherList))
The result:
['I', 'just', 'try', 'to', 'acomplish', 'this', 'foo', 'list']
originList = ['I', 'x-0', 'x-1','to', 'acomplish', 'x-2','foo', 'x-3']
anotherList = ['just','try','this','list']
res = []
i=0
for index in originList:
if 'x' in index:
res.append(anotherList[i])
i += 1
else:
res.append(index)
print res
you can get right result!
But,I think you have use string.format(like this)
print '{0}{1}{2}{3}'.format('a', 'b', 'c', 123) #abc123
Read python docs - string
Related
I am very very new to python so I'm still figuring out the basics.
I have a nested list with each element containing two strings like so:
mylist = [['Wowza', 'Here is a string'],['omg', 'yet another string']]
I would like to iterate through each element in mylist, and split the second string into multiple strings so it looks like:
mylist = [['wowza', 'Here', 'is', 'a', 'string'],['omg', 'yet', 'another', 'string']]
I have tried so many things, such as unzipping and
for elem in mylist:
mylist.append(elem)
NewList = [item[1].split(' ') for item in mylist]
print(NewList)
and even
for elem in mylist:
NewList = ' '.join(elem)
def Convert(string):
li = list(string.split(' '))
return li
print(Convert(NewList))
Which just gives me a variable that contains a bunch of lists
I know I'm way over complicating this, so any advice would be greatly appreciated
You can use list comprehension
mylist = [['Wowza', 'Here is a string'],['omg', 'yet another string']]
req_list = [[i[0]]+ i[1].split() for i in mylist]
# [['Wowza', 'Here', 'is', 'a', 'string'], ['omg', 'yet', 'another', 'string']]
I agree with #DeepakTripathi's list comprehension suggestion (+1) but I would structure it more descriptively:
>>> mylist = [['Wowza', 'Here is a string'], ['omg', 'yet another string']]
>>> newList = [[tag, *words.split()] for (tag, words) in mylist]
>>> print(newList)
[['Wowza', 'Here', 'is', 'a', 'string'], ['omg', 'yet', 'another', 'string']]
>>>
You can use the + operator on lists to combine them:
a = ['hi', 'multiple words here']
b = []
for i in a:
b += i.split()
I have a list of strings like the one below, written in Python. What I want to do now is to get the number of occurences of the string 'you' after each string 'hello'. The output should then be something like the number 0 for the first two 'hello's , the number 2 for the third 'hello', number 1 for the fourth 'hello' and so on.
Does anyone know how to that exactly?
my_list = ['hello', 'hello', 'hello', 'you', 'you', 'hello', 'you', 'hello',
'you', 'you', 'you', ...]
Update:
Solved it myself, though Karan Elangovans approach also works:
This is how i did it:
list_counter = []
counter = 0
# I reverse the list because the loop below counts the number of
# occurences of 'you' behind each 'hello', not in front of it
my_list_rev = reversed(my_list)
for m in my_list_rev:
if m == 'you':
counter += 1
elif m == 'hello':
list_counter.append(counter)
counter = 0
# reverse the output to match it with my_list
list_counter = list(reversed(list_counter))
print(list_counter)
This outputs:
[0, 0, 2, 1, 3]
for:
my_list = ['hello', 'hello', 'hello', 'you', 'you', 'hello', 'you', 'hello',
'you', 'you', 'you']
Maybe not the best approach, as you have to reverse both the original list and the list with the results to get the correct output, but it works for this problem.
Try this one-liner:
reduce(lambda acc, cur: acc + ([] if cur[1] == 'you' else [next((i[0] - cur[0] - 1 for i in list(enumerate(my_list))[cur[0]+1:] if i[1] == 'hello'), len(my_list) - cur[0] - 1)]), enumerate(my_list), [])
It will give an array where the nth element is the number of 'you's following the nth occurrence of 'hello'.
e.g.
If my_list = ['hello', 'hello', 'hello', 'you', 'you', 'hello', 'you', 'hello', 'you', 'you', 'you'],
it will give: [0, 0, 2, 1, 3]
I've dug through countless other questions but none of them seem to work for me. I've also tried a ton of different things but I don't understand what I need to do. I don't know what else to do.
list:
split_me = ['this', 'is', 'my', 'list', '--', 'and', 'thats', 'what', 'it', 'is!', '--', 'Please', 'split', 'me', 'up.']
I need to:
Split this into a new list everytime it finds a "--"
name the list the first value after the "--"
not include the "--" in the new lists.
So it becomes this:
this=['this', 'is', 'my', 'list']
and=['and', 'thats', 'what', 'it', 'is!']
please=['Please', 'split', 'me', 'up.']
current attempt (Work in progress):
for value in split_me:
if firstrun:
newlist=list(value)
firstrun=False
continue
if value == "--":
#restart? set firstrun to false?
firstrun=False
continue
else:
newlist.append(value)
print(newlist)
This more or less works, although I had to change words to solve the reserved word problem. (Bad idea to call a variable 'and').
split_me = ['This', 'is', 'my', 'list', '--', 'And', 'thats', 'what', 'it', 'is!', '--', 'Please', 'split', 'me', 'up.']
retval = []
actlist = []
for e in split_me:
if (e == '--'):
retval.append(actlist)
actlist = []
continue
actlist.append(e)
if len(actlist) != 0:
retval.append(actlist)
for l in retval:
name = l[0]
cmd = name + " = " + str(l)
exec( cmd )
print This
print And
print Please
Utilizing itertools.groupby():
dash = "--"
phrases = [list(y) for x, y in groupby(split_me, lambda z: z == dash) if not x]
Initialize a dict and map each list to the first word in that list:
myDict = {}
for phrase in phrases:
myDict[phrase[0].lower()] = phrase
Which will output:
{'this': ['this', 'is', 'my', 'list]
'and': ['and', 'thats', 'what', 'it', 'is!']
'please': ['Please', 'split', 'me', 'up.'] }
This will actually create global variables named the way you want them to be named. Unfortunately it will not work for Python keywords such as and and for this reason I am replacing 'and' with 'And':
split_me = ['this', 'is', 'my', 'list', '--', 'And', 'thats', 'what', 'it',
'is!', '--', 'Please', 'split', 'me', 'up.']
new = True
while split_me:
current = split_me.pop(0)
if current == '--':
new = True
continue
if new:
globals()[current] = [current]
newname = current
new = False
continue
globals()[newname].append(current)
A more elegant approach based on #Mangohero1 answer would be:
from itertools import groupby
dash = '--'
phrases = [list(y) for x, y in groupby(split_me, lambda z: z == dash) if not x]
for l in phrases:
if not l:
continue
globals()[l[0]] = l
I would try something ike
" ".join(split_me).split(' -- ') # as a start
Using the following code from https://stackoverflow.com/a/11899925, I am able to find if a word is unique or not (by comparing if it was used once or greater than once):
helloString = ['hello', 'world', 'world']
count = {}
for word in helloString :
if word in count :
count[word] += 1
else:
count[word] = 1
But, if I were to have a string with hundreds of words, how would I be able to count the number of unique words within that string?
For example, my code has:
uniqueWordCount = 0
helloString = ['hello', 'world', 'world', 'how', 'are', 'you', 'doing', 'today']
count = {}
for word in words :
if word in count :
count[word] += 1
else:
count[word] = 1
How would I be able to set uniqueWordCount to 6? Usually, I am really good at solving these types of algorithmic puzzles, but I have been unsuccessful with figuring this one out. I feel as if it is right beneath my nose.
The best way to solve this is to use the set collection type. A set is a collection in which all elements are unique. Therefore:
unique = set([ 'one', 'two', 'two'])
len(unique) # is 2
You can use a set from the outset, adding words to it as you go:
unique.add('three')
This will throw out any duplicates as they are added. Or, you can collect all the elements in a list and pass the list to the set() function, which will remove the duplicates at that time. The example I provided above shows this pattern:
unique = set([ 'one', 'two', 'two'])
unique.add('three')
# unique now contains {'one', 'two', 'three'}
Read more about sets in Python.
You have many options for this, I recommend a set, but you can also use a counter, which counts the amount a number shows up, or you can look at the number of keys for the dictionary you made.
Set
You can also convert the list to a set, where all elements have to be unique. Not unique elements are discarded:
helloString = ['hello', 'world', 'world', 'how', 'are', 'you', 'doing', 'today']
helloSet = set(helloString) #=> ['doing', 'how', 'are', 'world', 'you', 'hello', 'today']
uniqueWordCount = len(set(helloString)) #=> 7
Here's a link to further reading on sets
Counter
You can also use a counter, which can also tell you how often a word was used, if you still need that information.
from collections import Counter
helloString = ['hello', 'world', 'world', 'how', 'are', 'you', 'doing', 'today']
counter = Counter(helloString)
len(counter) #=> 7
counter["world"] #=> 2
Loop
At the end for your loop, you can check the len of count, also, you mistyped helloString as words:
uniqueWordCount = 0
helloString = ['hello', 'world', 'world', 'how', 'are', 'you', 'doing', 'today']
count = {}
for word in helloString:
if word in count :
count[word] += 1
else:
count[word] = 1
len(count) #=> 7
You can use collections.Counter
helloString = ['hello', 'world', 'world']
from collections import Counter
c = Counter(helloString)
print("There are {} unique words".format(len(c)))
print('They are')
for k, v in c.items():
print(k)
I know the question doesn't specifically ask for this, but to maintain order
helloString = ['hello', 'world', 'world', 'how', 'are', 'you', 'doing', 'today']
from collections import Counter, OrderedDict
class OrderedCounter(Counter, OrderedDict):
pass
c = OrderedCounter(helloString)
print("There are {} unique words".format(len(c)))
print('They are')
for k, v in c.items():
print(k)
In your current code you can either increment uniqueWordCount in the else case where you already set count[word], or just lookup the number of keys in the dictionary: len(count).
If you only want to know the number of unique elements, then get the elements in the set: len(set(helloString))
I would do this using a set.
def stuff(helloString):
hello_set = set(helloString)
return len(hello_set)
Counter is the efficient way to do it.
This code is similar to counter,
text = ['hello', 'world']
# create empty dictionary
freq_dict = {}
# loop through text and count words
for word in text:
# set the default value to 0
freq_dict.setdefault(word, 0)
# increment the value by 1
freq_dict[word] += 1
for key,value in freq_dict.items():
if value == 1:
print(f'Word "{key}" has single appearance in the list')
Word "hello" has single appearance in the list
Word "world" has single appearance in the list
[Program finished]
I may be misreading the question but I believe the goal is to find all elements which only occur one time in the list.
from collections import Counter
helloString = ['hello', 'world', 'world', 'how', 'are', 'you', 'doing', 'today']
counter = Counter(helloString)
uniques = [value for value, count in counter.items() if count == 1]
This will give us 6 items because "world" occurs twice in our list:
>>> uniques
['you', 'are', 'doing', 'how', 'today', 'hello']
Say I have a list...
['a','brown','cat','runs','another','cat','jumps','up','the','hill']
...and I want to go through that list and return all instances of a specific item as well as the 2 items leading up to and proceeding that item. Exactly like this if I am searching for 'cat'
[('a','brown','cat','runs','another'),('runs','another','cat','jumps','up')]
the order of the returned list of tuples is irrelevant, ideally the code handle instances where the word was the first or last in a list, and an efficient and compact piece of code would be better of course.
Thanks again everybody, I am just getting my feet wet in Python and everybody here has been a huge help!
Without error checking:
words = ['a','brown','cat','runs','another','cat','jumps','up','the','hill']
the_word = 'cat'
seqs = []
for i, word in enumerate(words):
if word == the_word:
seqs.append(tuple(words[i-2:i+3]))
print seqs #Prints: [('a', 'brown', 'cat', 'runs', 'another'), ('runs', 'another', 'cat', 'jumps', 'up')]
A recursive solution:
def context(ls, s):
if not s in ls: return []
i = ls.index('cat')
return [ tuple(ls[i-2:i+3]) ] + context(ls[i + 1:], s)
ls = ['a','brown','cat','runs','another','cat','jumps','up','the','hill']
print context(ls, 'cat')
Gives:
[('a','brown','cat','runs','another'),('runs','another','cat','jumps','up')]
With error checking:
def grep(in_list, word):
out_list = []
for i, val in enumerate(in_list):
if val == word:
lower = i-2 if i-2 > 0 else 0
upper = i+3 if i+3 < len(in_list) else len(in_list)
out_list.append(tuple(in_list[lower:upper]))
return out_list
in_list = ['a', 'brown', 'cat', 'runs', 'another', 'cat', 'jumps', 'up', 'the', 'hill']
grep(in_list, "cat")
# output: [('a', 'brown', 'cat', 'runs', 'another'), ('runs', 'another', 'cat', 'jumps', 'up')]
grep(in_list, "the")
# output: [('jumps', 'up', 'the', 'hill')]