How to index into the string result of a dictionary item reference? - python

What is the best syntax to reference the characters in a reference to dictionary item? How do I make it indexable?
>>> myd = {'abc':'123','def':'456','ghi':'789'}
>>> myd
{'def': '456', 'ghi': '789', 'abc': '123'}
>>> type(myd)
<class 'dict'>
>>> s=myd['def']
>>> s
'456'
>>> type(s)
<class 'str'>
>>> s[0]
'4'
>>> s[2]
'6'
>>> myd['def'].[0]
SyntaxError: invalid syntax

myd['def'] returns you the string '456'. You can access a specific index of an array using the same bracket notation that most languages support. Hence, myd['def'][0] will return the string literal '4'

Just remove the . and it will work.
You have not actually sliced your string. Once you get the value myd['def'] it returns a string. You then need to use [] to slice it. [0] in this case however adding a . is just a syntax error in Python.
This link describes slicing strings

Related

How to strip a tuple which is in a Python list

my_list = [(101)]
Output: my_list = [101]
If number of elements are more than 1 in my_list then i can run for loop and can strip the tuple from the list , but when number of element is one, then for loop also gives an error .Error :int object is not iterable.
Because single int surrounded by () has type int.
>>> t = (1)
>>> type(t)
<class 'int'>
You can use , to make it tuple. (if it has only one value.)
>>> t = (1,)
>>> type(t)
<class 'tuple'>
Assuming the first element of list is tuple.
my_list = [(101)]
if isinstance(my_list[0], tuple):
my_list = [i for i in my_list[0]]
print(my_list)
In case of single element, my_list will evaluate to what you expect

output for str.join() method is not consistent

Lets assign two variables:
>>> a_id = 'c99faf24275d476d84e0c8f0ad953582'
>>> u_id = '59958a11a6ad4d8b39707a70'
Right output:
>>> a_id+u_id
'c99faf24275d476d84e0c8f0ad95358259958a11a6ad4d8b39707a70'
Wrong output:
>>> str.join(a_id,u_id)
'5c99faf24275d476d84e0c8f0ad9535829c99faf24275d476d84e0c8f0ad9535829c99faf24275d476d84e0c8f0ad9535825c99faf24275d476d84e0c8f0ad9535828c99faf24275d476d84e0c8f0ad953582ac99faf24275d476d84e0c8f0ad9535821c99faf24275d476d84e0c8f0ad9535821c99faf24275d476d84e0c8f0ad953582ac99faf24275d476d84e0c8f0ad9535826c99faf24275d476d84e0c8f0ad953582ac99faf24275d476d84e0c8f0ad953582dc99faf24275d476d84e0c8f0ad9535824c99faf24275d476d84e0c8f0ad953582dc99faf24275d476d84e0c8f0ad9535828c99faf24275d476d84e0c8f0ad953582bc99faf24275d476d84e0c8f0ad9535823c99faf24275d476d84e0c8f0ad9535829c99faf24275d476d84e0c8f0ad9535827c99faf24275d476d84e0c8f0ad9535820c99faf24275d476d84e0c8f0ad9535827c99faf24275d476d84e0c8f0ad953582ac99faf24275d476d84e0c8f0ad9535827c99faf24275d476d84e0c8f0ad9535820'
Now consider this case, the output is correct now:
>>> a="asdf"
>>> b="asdfsdfsd"
>>> str.join(a,b)
'aasdfsasdfdasdffasdfsasdfdasdffasdfsasdfd'
Confirming the type of all variables in the example:
>>> type(a)
<class 'str'>
>>> type(a_id)
<class 'str'>
>>> type(u_id)
<class 'str'>
Edit
I just realized the second case in the output was not quite what I expected as well. I was using join method in a wrong way.
str.join(a, b) is equivalent to a.join(b), provided a is a str object and b is an iterable. Strings are always iterable, as you will be iterating though each characters in it when you're iterating over a string.
This is basically "insert a copy of a between every element of b (as an iterable)", so if a and b are both strings, a copy of a is inserted into every pair of letters in b. For example:
>>> str.join(".", "123456")
'1.2.3.4.5.6'
If you simply want to concatenate two strings, + is enough, not join:
>>> "." + "123456"
'.123456'
If you really want join, put the strings in a list and use an empty string as "delimiter":
>>> str.join('', ['123', '456', '7890'])
'1234567890'
>>> ''.join(['123', '456', '7890'])
'1234567890'

Python dictionary printing first word behaviour

I'm learning python and am on the topic of dictionaries. I wrote the following dictionary:
Team={
('projectmanager','Asma'): 'Sara',
('ba','Richard'): 'Steve',
('tester','Asma'): 'Rob',
'developer1': 'Misbah',
'developer2': 'Mariam'
}
I then wrote the following code:
for k,v in Team.items():
profile=type(k)
print('engTeam => {1} {0}'.format(k[0][0],profile))
The output I get is:
Team => <class 'str'> e
Team => <class 'str'> d
Team => <class 'tuple'> i
Team => <class 'str'> m
Team => <class 'tuple'> b
Team => <class 'str'> s
Team => <class 'tuple'> p
Team => <class 'str'> e
Team => <class 'str'> a
I don't understand why the first character of all non-tuple entries are being printed. If I think about it k[0][0] in my mind means get me the first element of the dictionary then the first sub element. But the non-tuple words don't have a sub element so the output should be blank, shouldn't it? Also k[0][0] should be printing the whole first word in the tuple e.g. 'projectmanager' instead of the first character of the first tuple word. What am I missing in understanding what k[0][0] means and what it is doing?
If I think about it k[0][0] in my mind means get me the first element of the dictionary then the first sub element.
No, k is the key of a given key-value pair. You are iterating over the items, which are those pairs:
for k,v in Team.items():
Each key-value pair is assigned to the names k and v there.
Given that you have two different types of keys in your dictionary, strings and tuples, your type() information shows you exactly that; you print a series of <class 'str'> and <class 'type'> for those keys.
So if k is a tuple, then k[0] is the first element in that tuple and k[0][0] is the first character of that first element:
>>> k = ('projectmanager', 'Asma')
>>> type(k)
<class 'tuple'>
>>> k[0]
'projectmanager'
>>> k[0][0]
'p'
For strings, k[0] would be the first character. But a single character is a string too. A string of length 1, so getting the first element of that string is still a string, again of length 1:
>>> k = 'developer1'
>>> type(k)
<class 'str'>
>>> k[0]
'd'
>>> type(k[0])
<class 'str'>
>>> len(k[0])
1
>>> k[0][0]
'd'
You wouldn't get an empty value here.
Consider,
First case- key, k is set to be a to be tuple. For instance ('projectmanager','Asma'). Hence obviously k[0][0] will print out p
Second case (the more tricky one) when k is set to be a string, k[0] is the first element of string. k[0] is hence a string of length 1. Doing
k[0][0] would access the first element of k[0] which is inturn the same as k[0] is a string of length 1.For example when k is 'developer1' ,k[0] is'd' and k[0][0] is hence 'd'
Hope this helps, good luck

python convert unicode to string

I got my results from sqlite by python, it's like this kind of tuples: (u'PR:000017512',)
However, I wanna print it as 'PR:000017512'. At first, I tried to select the first one in tuple by using index [0]. But the print out results is still u'PR:000017512'. Then I used str() to convert and nothing changed. How can I print this without u''?
You're confusing the string representation with its value. When you print a unicode string the u doesn't get printed:
>>> foo=u'abc'
>>> foo
u'abc'
>>> print foo
abc
Update:
Since you're dealing with a tuple, you don't get off this easy: You have to print the members of the tuple:
>>> foo=(u'abc',)
>>> print foo
(u'abc',)
>>> # If the tuple really only has one member, you can just subscript it:
>>> print foo[0]
abc
>>> # Join is a more realistic approach when dealing with iterables:
>>> print '\n'.join(foo)
abc
Don't see the problem:
>>> x = (u'PR:000017512',)
>>> print x
(u'PR:000017512',)
>>> print x[0]
PR:000017512
>>>
You the string is in unicode format, but it still means PR:000017512
Check out the docs on String literals
http://docs.python.org/2/reference/lexical_analysis.html#string-literals
In [22]: unicode('foo').encode('ascii','replace')
Out[22]: 'foo'

Interpreting Strings as Other Data Types in Python

I'm reading a file into python 2.4 that's structured like this:
field1: 7
field2: "Hello, world!"
field3: 6.2
The idea is to parse it into a dictionary that takes fieldfoo as the key and whatever comes after the colon as the value.
I want to convert whatever is after the colon to it's "actual" data type, that is, '7' should be converted to an int, "Hello, world!" to a string, etc. The only data types that need to be parsed are ints, floats and strings. Is there a function in the python standard library that would allow one to make this conversion easily?
The only things this should be used to parse were written by me, so (at least in this case) safety is not an issue.
First parse your input into a list of pairs like fieldN: some_string. You can do this easily with re module, or probably even simpler with slicing left and right of the index line.strip().find(': '). Then use a literal eval on the value some_string:
>>> import ast
>>> ast.literal_eval('6.2')
6.2
>>> type(_)
<type 'float'>
>>> ast.literal_eval('"Hello, world!"')
'Hello, world!'
>>> type(_)
<type 'str'>
>>> ast.literal_eval('7')
7
>>> type(_)
<type 'int'>
You can attempt to convert it to an int first using the built-in function int(). If the string cannot be interpreted as an int a ValueError exception is raised. You can then attempt to convert to a float using float(). If this fails also then just return the initial string
def interpret(val):
try:
return int(val)
except ValueError:
try:
return float(val)
except ValueError:
return val
You can use yaml to parse the literals which is better than ast in that it does not throw you an error if strings are not wrapped around extra pairs of apostrophes or quotation marks.
>>> import yaml
>>> yaml.safe_load('7')
7
>>> yaml.safe_load('Hello')
'Hello'
>>> yaml.safe_load('7.5')
7.5
For older python versions, like the one being asked, the eval function can be used but, to reduce evilness, a dict to be the global namespace should be used as second argument to avoid function calls.
>>> [eval(i, {"__builtins__":None}) for i in ['6.2', '"Hello, world!"', '7']]
[6.2, 'Hello, world!', 7]
Since the "only data types that need to be parsed are int, float and str", maybe somthing like this will work for you:
entries = {'field1': '7', 'field2': "Hello, world!", 'field3': '6.2'}
for k,v in entries.items():
if v.isdecimal():
conv = int(v)
else:
try:
conv = float(v)
except ValueError:
conv = v
entries[k] = conv
print(entries)
# {'field2': 'Hello, world!', 'field3': 6.2, 'field1': 7}
There is strconv lib.
In [22]: import strconv
/home/tworec/.local/lib/python2.7/site-packages/strconv.py:200: UserWarning: python-dateutil is not installed. As of version 0.5, this will be a hard dependency of strconv fordatetime parsing. Without it, only a limited set of datetime formats are supported without timezones.
warnings.warn('python-dateutil is not installed. As of version 0.5, '
In [23]: strconv.convert('1.2')
Out[23]: 1.2
In [24]: type(strconv.convert('1.2'))
Out[24]: float
In [25]: type(strconv.convert('12'))
Out[25]: int
In [26]: type(strconv.convert('true'))
Out[26]: bool
In [27]: type(strconv.convert('tRue'))
Out[27]: bool
In [28]: type(strconv.convert('12 Jan'))
Out[28]: str
In [29]: type(strconv.convert('12 Jan 2018'))
Out[29]: str
In [30]: type(strconv.convert('2018-01-01'))
Out[30]: datetime.date
Hope this helps to do what you are trying to do:
#!/usr/bin/python
a = {'field1': 7}
b = {'field2': "Hello, world!"}
c = {'field3': 6.2}
temp1 = type(a['field1'])
temp2 = type(b['field2'])
temp3 = type(c['field3'])
print temp1
print temp2
print temp3
Thanks to wim for helping me figure out what I needed to search for to figure this out.
One can just use eval():
>>> a=eval("7")
>>> b=eval("3")
>>> a+b
10
>>> b=eval("7.2")
>>> a=eval("3.5")
>>> a+b
10.699999999999999
>>> a=eval('"Hello, "')
>>> b=eval('"world!"')
>>> a+b
'Hello, world!'

Categories