I have a string as follows
144.963286 -37.814212 144.964498 -37.813854 144.964962 -37.814806 144.963711, -37.815168
I want to convert above string to an array such as below:
[(144.963286, -37.814212), (144.964498, -37.813854), (144.964962, -37.814806), (144.963711, -37.815168)]
Azat Ibrakov
11.1k9 gold badges43 silver badges58 bronze badges
asked Jan 27, 2019 at 6:49
Mahdi
8271 gold badge13 silver badges36 bronze badges
-
Array or list? They're very different.Mad Physicist– Mad Physicist2019年01月27日 06:56:46 +00:00Commented Jan 27, 2019 at 6:56
3 Answers 3
Assuming that you are using dot for separating decimal part from fractional one (and commas are not needed) we can
- Remove commas in string.
- Split string by whitespace.
- Convert each of substrings to floating number.
zipfloats into pairs.
like
>>> string = '144.963286 -37.814212 144.964498 -37.813854 144.964962 -37.814806 144.963711, -37.815168'
>>> floats = map(float, string.replace(',', '').split()) # use `itertools.imap` instead of `map` in Python2
>>> list(zip(floats, floats))
[(144.963286, -37.814212), (144.964498, -37.813854), (144.964962, -37.814806), (144.963711, -37.815168)]
As @AlexanderReynolds suggested we can use itertools.zip_longest function instead of zip for cases with odd number of arguments with some sort of fillvalue (default is None) like
>>> string = '144.963286, -37.814212 42'
>>> floats = map(float, string.replace(',', '').split())
>>> from itertools import zip_longest
>>> list(zip_longest(floats, floats,
fillvalue=float('inf')))
[(144.963286, -37.814212), (42.0, inf)]
also we can do it in one (pretty complex though) line with itertools.repeat like
>>> from itertools import repeat
>>> list(zip_longest(*repeat(map(float, string.replace(',', '').split()),
times=2),
fillvalue=float('inf')))
[(144.963286, -37.814212), (42.0, inf)]
answered Jan 27, 2019 at 6:56
Azat Ibrakov
11.1k9 gold badges43 silver badges58 bronze badges
Sign up to request clarification or add additional context in comments.
3 Comments
Azat Ibrakov
@zwer: in Python3
map will return iterator, so it should be fine, tested on Python3.6zwer
Ooops, didn't notice the tag, I was looking at marking the question as a duplicate of a similar one tagged with 2.x when your answer popped up. Sorry about that. ⚘
alkasm
Might be good to suggest
zip_longest for a string with an odd number of floats.Use zip with slicing:
s = '144.963286 -37.814212 144.964498 -37.813854 144.964962 -37.814806 144.963711 -37.815168'
splitted = s.split()
result = list(zip(splitted[::2], splitted[1::2]))
# [('144.963286', '-37.814212'), ('144.964498', '-37.813854'), ('144.964962', '-37.814806'), ('144.963711', '-37.815168')]
answered Jan 27, 2019 at 6:54
Austin
26.1k4 gold badges28 silver badges52 bronze badges
3 Comments
iz_
Why not just
list(zip(splitted[::2], splitted[1::2]))?Mykola Zotko
OP needs floats and not strings
iElden
for get float insead of string, you can change
splitted = s.split() to splitted = [float(i) for i in s.split()]You can use regex:
import re
s = '144.963286 -37.814212 144.964498 -37.813854 144.964962 -37.814806 144.963711, -37.815168'
pattern = r'(-?\d+\.\d+).+?(-?\d+\.\d+)'
new_s = [(float(i.group(1)), float(i.group(2))) for i in re.finditer(pattern, s)]
# [(144.963286, -37.814212), (144.964498, -37.813854), (144.964962, -37.814806), (144.963711, -37.815168)]
answered Jan 27, 2019 at 8:45
Mykola Zotko
18.2k7 gold badges88 silver badges91 bronze badges
Comments
lang-py