This question already has answers here:
Modifying list while iterating [duplicate]
(7 answers)
Closed 5 years ago.
Text = input('please enter your text')
l = [str(x) for x in Text.split()]
count = 0
for item in l:
for i in range(1,len(item)):
if item[i-1] == item[i]:
count +=1
if count <1:
l.remove(item)
count = 0
print (l)
the goal is : if we have a text : 'baaaaah mooh lpo mpoo' to get a list with elements they have 2 successive same characters, in this case ['baaaaah', 'mooh', 'mpoo' ]
the program is working with the mentioned example
if i use this one it's not working : 'hgj kio mpoo'
thank you
(complex)One liner:
>>> def successive_items(s):
return [x for x in s.split() if any(x[i]==x[i-1] for i in range(1,len(x)))]
>>> successive_items('baaaaah mooh lpo mpoo')
['baaaaah', 'mooh', 'mpoo']
>>> successive_items('hgj kio mpoo')
['mpoo']
In case of your code, you should not modify the list you are iterating over. Say, for example, lets have an array:
a = [1,2,3,4,5]
Now, if you iterate and remove elements (inside the loop), you would expect a to be empty. But let's check out:
>>> a = [1,2,3,4,5]
>>> for item in a:
a.remove(item)
>>> a
[2, 4]
See? It is not empty. This is better explained here.
Your program is not working for the second case because of list modification. Here is how:
Initially your list had ['hgj','kio','mpoo'].
After reading the first element you removed hgj. So the list now becomes ['kio','mpoo'].
The loop iterates the 2nd element next, and it gets mpoo (in the modified list);
kio was never read.
This might help:
sentence = input("please enter your text")
words = sentence.split()
answers = []
for each_word in words:
for idx in range(1, len(each_word)):
if each_word[idx] == each_word[idx-1]:
answers.append(each_word)
break
print(answers)
In your code, you are iterating over a list and at the same time you are modifying that very same list(by deleting elements from it), for more explanation see this answer
Related
This question already has answers here:
Checking if list is a sublist
(24 answers)
Closed 1 year ago.
I got a a list of numbers:
l = [1,2,3]
And I want to check if the numbers in that list are inside another list, like this one
l2 = [2,5,1,3,4]
This one should return True
Any ideas? Thanks a ton!
Use sets:
print(set(l) <= set(l2))
# True
From the docs:
set <= other
Test whether every element in the set is in other.
all() method would check if list 1 is in list 2. For example:
l = [1,2,3]
l2 = [2,5,1,3,4]
status = all(item in l for item in l2)
In this case, status will be True as 1,2,3 are in l2. I hope, this answers your query.
Try this :-
l = [1,2,3]
l2 = [2,5,1,3,4]
for i in l:
for j in l2:
if i == j:
break
print(True)
The result will be True in the end.
This question already has answers here:
How can I read inputs as numbers?
(10 answers)
Closed 3 years ago.
I want to cast elements in a list (string to integer)
Can't find what my mistake is. I just get strings.
Some other post answers suggest list comprehensions, but, being a newbie, I prefer understanding why this more basic approach doesn't work, before learning list comprehensions.
Thanks for your help.
(Using Python 3)
I tried:
while True:
userInput=input("Write space-separated numbers: ")
listNumbers=userInput.split()
for i in listNumbers:
int(i)
print(type(listNumbers[0]))
Also tried:
for i in listNumbers:
i=int(i)
I expect the type(listNumbers[0]) or whatever index number to return integer
but the output is still a string.
You must do:
for i in range(0, len(listNumbers)):
listNumbers[i] = int(listNumbers[i])
or:
for idx, val in enumerate(listNumbers):
listNumbers[idx] = value
This can be shortened using:
listNumbers = [int(x) for x in listNumbers]
When doing:
for i in listNumbers):
i = int(i)
i is only a reference to the elements so you can't change the original value of the list.
When doing:
for i in listNumbers:
int(i)
You don't store the result of int(i).
The problem comes from the fact that you do not store the integer in the loop !
Do :
mylist = []
for i in listNumbers:
mylist.append(int(i))
The best solution is
listNumbers = list(map(int, listNumbers))
int(i) does not convert the element i in the list to an integer, you would need to explicitly assign int(i) back to the element in the list for that to happen
while True:
userInput=input("Write space-separated numbers: ")
listNumbers=userInput.split()
#Iterate over the list and get index and element of list
for idx, i in enumerate(listNumbers):
#Cast string to int and assign back to list
listNumbers[idx] = int(i)
#Get the type
print(type(listNumbers[0]))
The output will be
Write space-separated numbers: 1 3 5
<class 'int'>
you need to actually save your modified value back into the list
for i,val in enumerate(my_list):
my_list[i] = int(val)
but as mentioned its much better to just use a list comprehension
new_list = [int(val) for val in my_list]
Your first variant doesn't do anything, because the cast value is just thrown away.
Your second variant does assign the value to i, but that doesn't change the value that is stored in the list.
I suggest using a list comprehension instead:
while True:
userInput=input("Write space-separated numbers: ")
listNumbers=[int(i) for i in userInput.split()]
print(type(listNumbers[0]))
This question already has answers here:
How do I split a string into a list of words?
(9 answers)
Closed 6 years ago.
i am trying to parse a xml file, it works very well. I have string output, which i would like to make as list, but i doesnot work.
I get for tuple or list, that every line is a list...Somebody any idea?
def handleToc(self,elements):
for element in elements:
self.name = element.getElementsByTagName("name")[0]
self.familyname = element.getElementsByTagName("family")[0]
#self.position = element.getElementsByTagName("position")[0].firstChild.nodeValue
position = element.getElementsByTagName("position")[0].firstChild.nodeValue
liste=position.encode('utf-8')
nameslist = [y for y in (x.strip() for x in liste.splitlines()) if y]
#print names_list[1:-1]
#print ''.join(repr(x).lstrip('u')[1:-1] for x in position)
#converted_degrees = {int(value) for value in position}
liste1=tuple(liste)
print liste
print list1
and the output is:
66.5499972
70.5500028
73.7
76.3
79.4499972
83.4500028
86.6
89.2
replace
listel= tuple(liste)
with
liste1 = liste.split(' ')
split(' ') will split the string into a list of items, and access it with index
say listel[0] for first item. liste1[1] for second item and so on.
This question already has answers here:
python lists, appending something to the list changes the entire thing?
(3 answers)
Closed 8 years ago.
x = raw_input("")
y = raw_input("")
a = []
b = []
count = 1
for i in range(0, int(y)):
b.append(count)
count+=1
for i in range(0, int(x)):
a.append(b)
for i in a:
print ""
for j in i:
print j,
a[1][1] = 0
for i in a:
print ""
for j in i:
print j,
a has been created by appending list "b" n time to it
Now when i modify a[1][1] the whole column that is a[0][1] - a[n][1] gets modified to that value
Can anyone explain why this is happening
Every time you append b, you are appending the same list -- not copies of the list, but multiple references to the same object. If you want each row to be a different list, you need to append a new list each time, by doing a.append(b[:]).
That is because by appending b, you are creating pointers to the same objects. Instead, make a copy as follows:
for i in range(0, int(x)):
a.append(b[:])
You can see it working as expected, here
This question already has answers here:
Removing elements that have consecutive duplicates
(9 answers)
Closed 3 years ago.
For a string such as '12233322155552', by removing the duplicates, I can get '1235'.
But what I want to keep is '1232152', only removing the consecutive duplicates.
import re
# Only repeated numbers
answer = re.sub(r'(\d)\1+', r'\1', '12233322155552')
# Any repeated character
answer = re.sub(r'(.)\1+', r'\1', '12233322155552')
You can use itertools, here is the one liner
>>> s = '12233322155552'
>>> ''.join(i for i, _ in itertools.groupby(s))
'1232152'
Microsoft / Amazon job interview type of question:
This is the pseudocode, the actual code is left as exercise.
for each char in the string do:
if the current char is equal to the next char:
delete next char
else
continue
return string
As a more high level, try (not actually the implementation):
for s in string:
if s == s+1: ## check until the end of the string
delete s+1
Hint: the itertools module is super-useful. One function in particular, itertools.groupby, might come in really handy here:
itertools.groupby(iterable[, key])
Make an iterator that returns consecutive keys and groups from
the iterable. The key is a function computing a key value for each
element. If not specified or is None, key defaults to an identity
function and returns the element unchanged. Generally, the iterable
needs to already be sorted on the same key function.
So since strings are iterable, what you could do is:
use groupby to collect neighbouring elements
extract the keys from the iterator returned by groupby
join the keys together
which can all be done in one clean line..
First of all, you can't remove anything from a string in Python (google "Python immutable string" if this is not clear).
M first approach would be:
foo = '12233322155552'
bar = ''
for chr in foo:
if bar == '' or chr != bar[len(bar)-1]:
bar += chr
or, using the itertools hint from above:
''.join([ k[0] for k in groupby(a) ])
+1 for groupby. Off the cuff, something like:
from itertools import groupby
def remove_dupes(arg):
# create generator of distinct characters, ignore grouper objects
unique = (i[0] for i in groupby(arg))
return ''.join(unique)
Cooks for me in Python 2.7.2
number = '12233322155552'
temp_list = []
for item in number:
if len(temp_list) == 0:
temp_list.append(item)
elif len(temp_list) > 0:
if temp_list[-1] != item:
temp_list.append(item)
print(''.join(temp_list))
This would be a way:
def fix(a):
list = []
for element in a:
# fill the list if the list is empty
if len(list) == 0:list.append(element)
# check with the last element of the list
if list[-1] != element: list.append(element)
print(''.join(list))
a= 'GGGGiiiiniiiGinnaaaaaProtijayi'
fix(a)
# output => GiniGinaProtijayi
t = '12233322155552'
for i in t:
dup = i+i
t = re.sub(dup, i, t)
You can get final output as 1232152