I have some problems with the following issue:
I have a string, which contains integers and floats. I fail to extract only the integers (NOT the floats!).
What i have (it is a string):
f= "0:6.0 3:5.6 54:12.3 56:12.0"
How the result should be (not in a string form):
0,3,54,56
I searched on Google (and stack-overflow) which leads to this solution:
[int(s) for s in f.split() if s.isdigit()]
That leads to a empty list.
Other solutions like:
int(re.search(r'\d+', f).group())
Leads to "0 integers". Sorry i'm new but I really can't solve this.
You can use .partition(':'):
>>> s="0:6.0 3:5.6 54:12.3 56:12.0"
>>> [e.partition(':')[0] for e in s.split()]
['0', '3', '54', '56']
Then call int on those strings:
>>> [int(e.partition(':')[0]) for e in s.split()]
[0, 3, 54, 56]
Or,
>>> map(int, (e.partition(':')[0] for e in s.split()))
[0, 3, 54, 56]
And you can use the same method (with a slight change) to get the floats:
>>> map(float, (e.partition(':')[2] for e in s.split()))
[6.0, 5.6, 12.3, 12.0]
Fair question asked in comments: Why use partition ? you can use int(split(":")[0])
With .partition it is clear to all readers (including your future self) that you are looking at 1 split only. (Granted, you could use the 2 argument form of split(delimiter, maxsplit) but I think that is less clear for a single split...)
It is easier to test successful partitioning since partition always produces a three element tuple and you only need to test the truthiness of the element tuple[1].
You can safely use .partion in tuple assignments of the form lh,delimiter,rh=string.partion('delimiter') where lh, rh=string.split('delimiter') will produce a ValueError if the delimiter is not found.
With the delimiter included in the resulting tuple, it is easier to reassemble the original string with ''.join(tuple_from_partion) vs split since the delimiter in split is lost.
Why not?
How about using the following regex:
import re
f = "0:6.0 3:5.6 54:12.3 56:12.0"
answer = [int(x) for x in re.findall(r'\d{1,2}(?=:)', f)]
print(answer)
Output
[0, 3, 54, 56]
You can also achieve the same result using map instead of a list comprehension (as in #dawg's answer):
answer = map(int, re.findall(r'\d{1,2}(?=:)', f))
Related
I wrote a code that accepts multiple numbers and converts them into a list of integers. But I get them with spaces.
For example: I enter as input: 1,2,3,4,5 (with commas).
I get a list of [1, 2, 3, 4, 5]
Now I just need to delete the spaces but It's not working, I need it to look something like this [1,2,3,4,5].
I tried doing it this way:
numbers = input().split(',')
for i in range(0, len(numbers)):
numbers[i] = int(numbers[i])
mylist = str(numbers).replace(' ','')
print(mylist)
This causes the square parentheses to be considered as items.
How do I delete the spaces the right way?
I think you are conflating the list and the representation of the list. The list itself doesn't have spaces, or even commas, it just has the items (in your case, the numbers). The representation of the list is just that - a way to represent the data inside of it in a normal, standard way. That standard includes commas and spaces.
If you want a new thing that represents the list and its items in the way you are saying, you can do that by making a new string just like that.
str(numbers).replace(' ','')
This has two functions in it, chained together. First, we do str(numbers) to get a string that is the string-representation of the list. This will be the string '[1, 2, 3, 4, 5]'. Then you replace any blank space-bar ' ' with nothing ''.
Edit:
I think I read your question too quickly and see that you did the exact same as what I have in my code here and said it isn't doing exactly what you want to do. I think the answer here is: no.
As I say in my first paragraph, there is the list and there is the lists representation. The function for the list's representation is a python built-in that can not be trivially overridden. I'm not saying it can't be done, but I don't think you'll get it done without defining some new things.
You can change the print behavior of the list to something you code yourself.
numbers = input().split(',')
for i in range(0, len(numbers)):
numbers[i] = int(numbers[i])
mylist = str(numbers).replace(' ','')
print('[' + ','.join([str(n) for n in numbers]) + ']')
This prints a bracket [, then each number separated by commas without any spaces, and finally the ending bracket ].
Output looks like this:
1, 2, 3, 4, 5
[1,2,3,4,5]
My understanding of your problem is that you want to input a list as a string and want to transform it into a Python list of numbers.
If you input the following string [1, 2, 3, 4, 5], then you can split on , . Then you need to consider removing the leftmost and rightmost character, that correspond to the brackets:
numbers = input()[1:-1].split(', ')
for i in range(len(numbers)):
numbers[i] = int(numbers[i])
print(numbers)
Other options to transform the numbers from strings to integers are the following:
Python built-in map function:
numbers = input()[1:-1].split(', ')
numbers = list(map(int, numbers))
print(numbers)
Python list comprehension:
numbers = input()[1:-1].split(', ')
numbers = [int(n) for n in numbers]
print(numbers)
What you might want to do is create a subclass of list that has the repr implementation you want. That way you can still operate on your list object as you would any other list (e.g. you can access numbers[0] and it will return the first number), but printing the list as a whole will produce the output you're looking for.
class MyList(list):
def __repr__(self) -> str:
return "[" + ",".join(repr(i) for i in self) + "]"
numbers = MyList(int(n) for n in input().split(","))
print(numbers)
print(numbers[0])
Input:
1,2,3,4,5
Output:
[1,2,3,4,5]
1
Since MyList is a list subclass, you can construct one from any iterable, including a generator expression (as in the code above) or an existing list, e.g.:
>>> n_copy = MyList(numbers)
>>> n_copy
[1,2,3,4,5]
You could use the re module's split function to deal with the whitespaces when splitting. Then you just need to join the elements with ',' and embed the whole thing between brackets in the string representation.
import re
numbers = re.split(r'\s*,\s*', input())
print(f"[{','.join(numbers)}]")
This question already has answers here:
Apply function to each element of a list
(4 answers)
Closed 8 months ago.
The community is reviewing whether to reopen this question as of 11 days ago.
I need to join a list of items. Many of the items in the list are integer values returned from a function; i.e.,
myList.append(munfunc())
How should I convert the returned result to a string in order to join it with the list?
Do I need to do the following for every integer value:
myList.append(str(myfunc()))
Is there a more Pythonic way to solve casting problems?
Calling str(...) is the Pythonic way to convert something to a string.
You might want to consider why you want a list of strings. You could instead keep it as a list of integers and only convert the integers to strings when you need to display them. For example, if you have a list of integers then you can convert them one by one in a for-loop and join them with ,:
print(','.join(str(x) for x in list_of_ints))
There's nothing wrong with passing integers to str. One reason you might not do this is that myList is really supposed to be a list of integers e.g. it would be reasonable to sum the values in the list. In that case, do not pass your ints to str before appending them to myList. If you end up not converting to strings before appending, you can construct one big string by doing something like
', '.join(map(str, myList))
The map function in python can be used. It takes two arguments. The first argument is the function which has to be used for each element of the list. The second argument is the iterable.
a = [1, 2, 3]
map(str, a)
['1', '2', '3']
After converting the list into a string you can use the simple join function to combine the list into a single string
a = map(str, a)
''.join(a)
'123'
There are three ways of doing this.
let say you have a list of integers
my_list = [100,200,300]
"-".join(str(n) for n in my_list)
"-".join([str(n) for n in my_list])
"-".join(map(str, my_list))
However as stated in the example of timeit on python website at https://docs.python.org/2/library/timeit.html using a map is faster. So I would recommend you using "-".join(map(str, my_list))
a=[1,2,3]
b=[str(x) for x in a]
print b
above method is the easiest and most general way to convert list into string. another short method is-
a=[1,2,3]
b=map(str,a)
print b
Your problem is rather clear. Perhaps you're looking for extend, to add all elements of another list to an existing list:
>>> x = [1,2]
>>> x.extend([3,4,5])
>>> x
[1, 2, 3, 4, 5]
If you want to convert integers to strings, use str() or string interpolation, possibly combined with a list comprehension, i.e.
>>> x = ['1', '2']
>>> x.extend([str(i) for i in range(3, 6)])
>>> x
['1', '2', '3', '4', '5']
All of this is considered pythonic (ok, a generator expression is even more pythonic but let's stay simple and on topic)
For example:
lst_points = [[313, 262, 470, 482], [551, 254, 697, 449]]
lst_s_points = [" ".join(map(str, lst)) for lst in lst_points]
print lst_s_points
# ['313 262 470 482', '551 254 697 449']
As to me, I want to add a str before each str list:
# here o means class, other four points means coordinate
print ['0 ' + " ".join(map(str, lst)) for lst in lst_points]
# ['0 313 262 470 482', '0 551 254 697 449']
Or single list:
lst = [313, 262, 470, 482]
lst_str = [str(i) for i in lst]
print lst_str, ", ".join(lst_str)
# ['313', '262', '470', '482'], 313, 262, 470, 482
lst_str = map(str, lst)
print lst_str, ", ".join(lst_str)
# ['313', '262', '470', '482'], 313, 262, 470, 482
Maybe you do not need numbers as strings, just do:
functaulu = [munfunc(arg) for arg in range(loppu)]
Later if you need it as string you can do it with string or with format string:
print "Vastaus5 = %s" % functaulu[5]
How come no-one seems to like repr?
python 3.7.2:
>>> int_list = [1, 2, 3, 4, 5]
>>> print(repr(int_list))
[1, 2, 3, 4, 5]
>>>
Take care though, it's an explicit representation. An example shows:
#Print repr(object) backwards
>>> print(repr(int_list)[::-1])
]5 ,4 ,3 ,2 ,1[
>>>
more info at pydocs-repr
So I have a string and I want to convert it to a list
input:
"123|456|890|60"
output:
[123,456,890,60]
Another example, input:
"123"
output:
[123]
Here is what I did until now.
A=input()
n=len(A)
i=0
z=0
K=""
Y=[0]*n
while(i<n):
if(A[i]=="|"):
Y[z]=int(Y[z])
j=+1
K=""
else:
Y[z]=K+A[i]
i+=1
print(Y)
Thanks for editing in your attempt. Splitting a string and converting a string to an integer are very common tasks, and Python has built in tools to achieve them.
str.split splits a string into a list by a given delimiter.
int can convert a string to an integer. You can use map to apply a function to all elements of a list.
>>> map(int, "123|456|890|60".split('|'))
[123, 456, 890, 60]
Using list comprehension
Code:
[int(a) for a in "123|456|890|60".split("|")]
Output:
[123, 456, 890, 60]
Notes:
Split creates a list of strings here where the current strings are split at |
We are looping over the list and converting the strings into int
Here's a similar approach, using regular expressions instead:
import re
def convert_string(s):
return map(int, re.findall(r'[0-9]+', s))
Or using a list comprehension:
import re
def convert_string(s):
return [int(num) for num in re.findall(r'[0-9]+', s)]
This is a more general approach and will work for any character (in this case '|') that separates the numbers in the input string.
I have a string and I need to generate a list of the lengths of all the sub-strings terminating in a given separator.
For example: string = 'a0ddb0gf0', separator = '0', so I need to generate: lengths = [2,4,3], since len('a0')==2, len('ddb0')=4, and len('gf0')==3.
I am aware that it can be done by the following (for example):
separators = [index for index in range(len(string)) if string[index]==separator]
lengths = [separators[index+1] - separators[index] for index in range(len(separators)-1)]
But I need it to be done extremely fast (on large amounts of data). Generating an intermediate list for large amounts of data is time consuming.
Is there a solution that does this neatly and fast (py2.7)?
Fastest? Don't know. You might like to profile it.
>>> print [len(s) for s in 'a0ddb0gf0'.split('0')]
[1, 3, 2, 0]
And, if you really don't want to include zero length strings:
>>> print [len(s) for s in 'a0ddb0gf0'.split('0') if s]
[1, 3, 2]
Personally, I love itertools.groupby()
>>> from itertools import groupby
>>> sep = '0'
>>> data = 'a0ddb0gf0'
>>> [sum(1 for i in g) for (k, g) in groupby(data, sep.__ne__) if k]
[1, 3, 2]
This groups the data according to whether each element is equal to the separator, then gets the length of each group for which the element was not equal (by summing 1's for each item in the group).
itertools functions are generally quite fast, though I don't know for sure how much better than split() this is. The one point that I think is strongly in its favor is that this can seamlessly handle multiple consecutive occurrences of the separator character. It will also handle any iterable for data, not just strings.
I don't know how fast this will go, but here's another way:
def len_pieces(s, sep):
i = 0
while True:
f = s.find(sep, i)
if f == -1:
yield len(s) - i
return
yield f - i + 1
i = f + 1
>>> [len(i) for i in re.findall('.+?0', 'a0ddb0gf0')]
[2, 4, 3]
You may use re.finditer to avoid an intermediary list, but it may not be much different in performance:
[len(i.group(0)) for i in re.finditer('.+?0', 'a0ddb0gf0')]
Maybe using an re:
[len(m.group()) for m in re.finditer('(.*?)0', s)]
This question already has answers here:
Apply function to each element of a list
(4 answers)
Closed 8 months ago.
The community reviewed whether to reopen this question 16 days ago and left it closed:
Original close reason(s) were not resolved
I need to join a list of items. Many of the items in the list are integer values returned from a function; i.e.,
myList.append(munfunc())
How should I convert the returned result to a string in order to join it with the list?
Do I need to do the following for every integer value:
myList.append(str(myfunc()))
Is there a more Pythonic way to solve casting problems?
Calling str(...) is the Pythonic way to convert something to a string.
You might want to consider why you want a list of strings. You could instead keep it as a list of integers and only convert the integers to strings when you need to display them. For example, if you have a list of integers then you can convert them one by one in a for-loop and join them with ,:
print(','.join(str(x) for x in list_of_ints))
There's nothing wrong with passing integers to str. One reason you might not do this is that myList is really supposed to be a list of integers e.g. it would be reasonable to sum the values in the list. In that case, do not pass your ints to str before appending them to myList. If you end up not converting to strings before appending, you can construct one big string by doing something like
', '.join(map(str, myList))
The map function in python can be used. It takes two arguments. The first argument is the function which has to be used for each element of the list. The second argument is the iterable.
a = [1, 2, 3]
map(str, a)
['1', '2', '3']
After converting the list into a string you can use the simple join function to combine the list into a single string
a = map(str, a)
''.join(a)
'123'
There are three ways of doing this.
let say you have a list of integers
my_list = [100,200,300]
"-".join(str(n) for n in my_list)
"-".join([str(n) for n in my_list])
"-".join(map(str, my_list))
However as stated in the example of timeit on python website at https://docs.python.org/2/library/timeit.html using a map is faster. So I would recommend you using "-".join(map(str, my_list))
a=[1,2,3]
b=[str(x) for x in a]
print b
above method is the easiest and most general way to convert list into string. another short method is-
a=[1,2,3]
b=map(str,a)
print b
Your problem is rather clear. Perhaps you're looking for extend, to add all elements of another list to an existing list:
>>> x = [1,2]
>>> x.extend([3,4,5])
>>> x
[1, 2, 3, 4, 5]
If you want to convert integers to strings, use str() or string interpolation, possibly combined with a list comprehension, i.e.
>>> x = ['1', '2']
>>> x.extend([str(i) for i in range(3, 6)])
>>> x
['1', '2', '3', '4', '5']
All of this is considered pythonic (ok, a generator expression is even more pythonic but let's stay simple and on topic)
For example:
lst_points = [[313, 262, 470, 482], [551, 254, 697, 449]]
lst_s_points = [" ".join(map(str, lst)) for lst in lst_points]
print lst_s_points
# ['313 262 470 482', '551 254 697 449']
As to me, I want to add a str before each str list:
# here o means class, other four points means coordinate
print ['0 ' + " ".join(map(str, lst)) for lst in lst_points]
# ['0 313 262 470 482', '0 551 254 697 449']
Or single list:
lst = [313, 262, 470, 482]
lst_str = [str(i) for i in lst]
print lst_str, ", ".join(lst_str)
# ['313', '262', '470', '482'], 313, 262, 470, 482
lst_str = map(str, lst)
print lst_str, ", ".join(lst_str)
# ['313', '262', '470', '482'], 313, 262, 470, 482
Maybe you do not need numbers as strings, just do:
functaulu = [munfunc(arg) for arg in range(loppu)]
Later if you need it as string you can do it with string or with format string:
print "Vastaus5 = %s" % functaulu[5]
How come no-one seems to like repr?
python 3.7.2:
>>> int_list = [1, 2, 3, 4, 5]
>>> print(repr(int_list))
[1, 2, 3, 4, 5]
>>>
Take care though, it's an explicit representation. An example shows:
#Print repr(object) backwards
>>> print(repr(int_list)[::-1])
]5 ,4 ,3 ,2 ,1[
>>>
more info at pydocs-repr