Python string get leading characters up to first comma - python

I have the following string:
strIn = "Head,0.000235532,0.43656735"
I would like to retrieve from this a variable type = "Head" and an array
vals = [0.000235532,0.43656735]
How can I do this using Python? I've considered using strIn[0],...,strIn[5] to get the type, but then I realized I'll get types of various lengths. Thanks.

If you're using Python 3, you can do
type_, *vals = strIn.split(',')
vals = [float(v) for v in vals] # Convert list of strings to list of floats.
This uses str.split to split the string into a list based on the provided character, and then uses Python 3's extended tuple unpacking to put the first value into type_ and the remaining values into vals. See this answer for more discussion on how to use tuple unpacking.
If you're on Python 2 you can't use the extended unpacking syntax, so you have to add an additional step:
str_list = strIn.split(',')
type_ = str_list[0]
vals = [float(v) for v in str_list[1:]]

As you are in python2 first split with , then use slicing and float function :
>>> none=strIn.split(',')[0]
>>> none
'Head'
>>> vals=map(float,strIn.split(',')[1:])
>>> vals
[0.000235532, 0.43656735]
As type is a built-in name recommended that dont use it !

Related

Python > passing variables of a string into a method

I'm looking to replace a list of characters (including escaped characters) with another.
for example:
l=['\n','<br>','while:','<while>','for:','<for>']
s='line1\nline2'
s.replace(l[0],[l[1])
but passing the list indices through the method produces no effect.
I've also tried using
s=l[1].join(s.split(l[0]))
How can I replace a list of characters with another without expressing the pairs each time in the function?
As I said in the comments, the problem with your code is that you assumed that the replace works in-place. It does not, you have to assign the value it returns to the variable.
But, there is a better way of doing it that involves dictionaries. Take a look:
d = {'\n': '<br>', 'while:': '<while>', 'for:': '<for>'}
s = 'line1\nline2\nwhile: nothing and for: something\n\nnothing special'
for k, v in d.items():
s = s.replace(k, v)
print(s) # line1<br>line2<br><while> nothing and <for> something<br><br>nothing special
The advantage of using dictionaries in this case is that you make it very straightforward what you want to replace and what with. Playing with the indexes is not something you want to do if you can avoid it.
Finally, if you are wondering how to convert your list to a dict you can use the following:
d = {k: v for k, v in zip(l[::2], l[1::2])}
which does not break even if your list has an odd number of elements.
l=['\n','<br>','while:','<while>','for:','<for>']
s='line1\nline2'
for i in range(0, len(l), 2):
s = s.replace(l[i], l[i+1])
You simply have to iterate over the list containing your desired pairs, stepping over 2 values each time. And then assign the result of the replacement to the variable itself (replace doesn't do inline replacement because strings are inmutable in Python)

String being treated as group of characters when iterated [duplicate]

This question already has answers here:
What is the syntax rule for having trailing commas in tuple definitions?
(10 answers)
Closed 5 months ago.
First, I've sorted out my issue when I found this:
in python: iterate over each string in a list
Originally I was getting what I thought was weird behavior when I would iterate over a "list" with a single string. In those instances, the string was being treated as a group of characters, and the iteration was sequentially returning each character in the string.
Being new to Python, I did not realize there's a somewhat strict difference between using [] and () to define a list. My list definitions were using (). However, when the lists would contain more than one string, the iteration was return each complete string sequentially. To illustrate:
list = ('string')
for i in list:
print i
Output:
s
t
r
i
n
g
But if i do this, that is, add a second string to the () group:
list = ('string','another string')
for i in list:
print i
It gets treated as if I used [] (as you're supposed to). Output:
string
another string
Now, I get the expected behavior either way if I use [] to define my lists, so that's what I'm doing now. I just thought this was interesting behavior.
Can someone point me towards some documentation that explains the way Python interprets parens, especially relative to strings?
I didn't see anything in the Python docs for data structures:
https://docs.python.org/3/tutorial/datastructures.html
Thanks!
That's because parentheses don't define lists. They sometimes define tuples (a, b), which are similar to lists, but even in the code you provide, that is not a tuple.
('string')
Is a parenthesized expression. It's value is 'string'.
('string',)
Is a 1-tuple that contains a single element, the string 'string'
In the first case, the parenthesis are ambiguous. Do you mean a single element tuple or do you mean a parenthesized expression? The Python parser assumes parenthesized expression. You then are iterating over the string:
>>> li = ('string')
>>> li
'string'
This is in contrast to creating a list literal or set literal with a single string literal since there is no ambiguity what you mean:
>>> ['string']
['string']
>>> {'string'}
set(['string'])
In the second case, you are creating a tuple with two elements and then iterating over that tuple:
>>> li = ('string','another string')
>>> li
('string', 'another string')
If you want the first case to act like the second case, add a comma to create a one element tuple:
>>> li = ('string',)
>>> li
('string',)
Or, you do not have to use parenthesis to define a tuple:
>>> 'string','another string'
('string', 'another string')
>>> 'string',
('string',)
The tuple constructor in this case is the comma which allows this idiom in Python for swapping values without a temporary variable:
>>> a='string'
>>> b='another string'
>>> a,b=b,a
>>> a
'another string'
>>> b
'string'
(And please do not use list as a variable name. That redefines the list function...)

String translate using dict

I want to replace letters in a character vector by other ones, using a dictionary created with dict, as follows
import string
trans1 = str.maketrans("abc","cda")
trans = dict(zip("abc","cda"))
out1 = "abcabc".translate(trans1)
out = "abcabc".translate(trans)
print(out1)
print(out)
The desired output is "cdacda"
What I get is
cdacda
abcabc
Now out1 is this desired output, but out is not. I can not figure out why this is the case. How can I use the dictionary created via dict in the translate function? So what do I have to change if I want to use translate with trans?
str.translate supports dicts perfectly well (in fact, it supports anything that supports indexing, i.e. __getitem__) – it's just that the key has to be the ordinal representation of the character, not the character itself.
Compare:
>>> "abc".translate({"a": "d"})
'abc'
>>> "abc".translate({ord("a"): "d"})
'dbc'
I do not think the method translate will accept a dictionary object. Aditionlly, you should look at what you are creating:
>>> dict(zip("abc","cda"))
{'c': 'a', 'a': 'c', 'b': 'd'}
I do not think that is what you wanted. zip pairs off correspondingly indexed elements from the first and second argument.
You could write a work around:
def translate_from_dict(original_text,dictionary_of_translations):
out = original_text
for target in dictionary_of_translations:
trans = str.maketrans(target,dictionary_of_translations[target])
out = out.translate(trans)
return out
trans = {"abc":"cda"}
out = translate_from_dict("abcabc",trans)
print(out)
Usage of the dict function to create the dictionary. Read the function definition.
>>> dict([("abc","cda")])
{"abc":"cda"}
The string.translate doesn't support dictionaries as arguments:
translate(s, table, deletions='')
translate(s,table [,deletions]) -> string
Return a copy of the string s, where all characters occurring
in the optional argument deletions are removed, and the
remaining characters have been mapped through the given
translation table, which must be a string of length 256. The
deletions argument is not allowed for Unicode strings.
So, you have to write your own function.
Also, revise your code as it wont run in any python version that I know. It has at least 2 exceptions.

python struct.pack(): pack multiple datas in a list or a tuple

Say i have a list or a tuple containing numbers of type long long,
x = [12974658, 638364, 53637, 63738363]
If want to struct.pack them individually, i have to use
struct.pack('<Q', 12974658)
or if i want to do it as multiple, then i have to explicitly mention it like this
struct.pack('<4Q', 12974658, 638364, 53637, 63738363)
But, how can i insert items in a list or tuple inside a struct.pack statement. I tried using for loop like this.
struct.pack('<4Q', ','.join(i for i in x))
got error saying expected string, int found, so i converted the list containing type int into str, now it gets much more complicated to pack them. Because the whole list gets converted into a string( like a single sentence).
As of now im doing some thing like
binary_data = ''
x = [12974658, 638364, 53637, 63738363]
for i in x:
binary_data += struct.pack('<Q', i)
And i unpack them like
struct.unpack('<4Q', binary_data)
My question: is there a better way around, like can i directly point a list or tuple inside the struct.pack statement, or probably a one liner ?
You can splat, I'm sorry "unpack the argument list":
>>> struct.pack("<4Q", *[1,2,3,4])
'\x01\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00\x00\x03\x00\x00\x00\x00\x00\x00\x00\x04\x00\x00\x00\x00\x00\x00\x00'
If the length of the list is dynamic, you can of course build the format string at runtime too:
>>> x = [1, 2] # This could be any list of integers, of course.
>>> struct.pack("<%uQ" % len(x), *x)
'\x01\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00\x00'

Converting a string to dictionary in python

I have the following string :
str = "{application.root.category.id:2}"
I would like to convert the above to a dictionary data type in python as in :
dict = {application.root.category.id:2}
I tried using eval() and this is the error I got:
AttributeError: java package 'application' has no attribute "root"
My current python is of <2.3 and I cannot update the python to >2.3 .
Any solutions ?
Python dictionaries have keys that needn't be strings; therefore, when you write {a: b} you need the quotation marks around a if it's meant to be a string. ({1:2}, for instance, maps the integer 1 to the integer 2.)
So you can't just pass something of the sort you have to eval. You'll need to parse it yourself. (Or, if it happens to be easier, change whatever generates it to put quotation marks around the keys.)
Exactly how to parse it depends on what your dictionaries might actually look like; for instance, can the values themselves be dictionaries, or are they always numbers, or what? Here's a simple and probably too crude approach:
contents = str[1:-1] # strip off leading { and trailing }
items = contents.split(',') # each individual item looks like key:value
pairs = [item.split(':',1) for item in items] # ("key","value"), both strings
d = dict((k,eval(v)) for (k,v) in pairs) # evaluate values but not strings
First, 'dict' is the type name so not good for the variable name.
The following, does precisely as you asked...
a_dict = dict([str.strip('{}').split(":"),])
But if, as I expect, you want to add more mappings to the dictionary, a different approach is required.
Suppose I have a string
str='{1:0,2:3,3:4}'
str=str.split('{}')
mydict={}
for every in str1.split(','):
z=every.split(':')
z1=[]
for every in z:
z1.append(int(every))
for k in z1:
mydict[z1[0]]=z1[1]
output:
mydict
{1: 0, 2: 1, 3: 4}

Categories

Resources