String translate using dict - python

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.

Related

assign a string to an empty list to convert to a char wise list, how to understand?

To convert a string to char-wise list, one way is to assign the string to an empty list. However, the physical process on the memory is unclear to me. Any help is appreciated.
An example
s = 'abc'
s_list = []
s_list[:5] = s
print(s_list)
The code will output:
['a', 'b', 'c']
Basically, I would like to understand:
Why there is no out of index error when you try to do slicing s_list[:5] on an empty list? As a matter of fact, you can do s_list[:] or s_list[x:] or s_list[:x] (x can be any integer), it wouldn't raise any error.
I would like to know what's happening at the assignment sign for s_list[:5] = s. Does Python do a automatic conversion from string to list before assign to s_list?
documentation of python std library, paragraph on sequence types
https://docs.python.org/3/library/stdtypes.html#sequence-types-list-tuple-range
see footnote #4
I believe that taking a slice of an existing list and assigning to it some iterable (including string) will use values of that iterable to fill the slice, e.g.
l=[];
l[0:5] = range(5);

different behavior in Python when creating set from constructor or literal

I am trying to create a Set structure in Python by using code below:
a = set ([1,2,3])
print (a)
a ={1,2,3}
print (a)
a = {'FG'}
print (a)
a = set('FG')
print (a)
output:
{1, 2, 3}
{1, 2, 3}
{'FG'}
{'F', 'G'}
while the set creation with a list of numbers leads to the same result using the two options,
I see that if the input type is a String the result that I expect is the second, i.e. create a set of characters, while the first result seems to ignore that a string is a sequence of characters, therefore I am confused.
The set() constructor takes an iterable as an argument and will create a set of each unique item in that iterable. In this case a string IS the iterable, so you are seeing a set composed of each character in the string.
To get a set strings, places the strings in a list or tuple.
set(['abc', 'efg'])
When you do a = {'FG'}, you define the set with one single element which is the string "FG".
Then, when you do a = set('FG'), you define a set using an iterable, but in that case the iterable is not a list but a string. The set function will find all unique elements in the specified iterable, so in that case it will find all unique characters in the given string.
If you wanted the two to output the same result, you would have to give the set function a list containing individual strings, for instance: a = set(["FG"]).
When passing integers, you're passing it in the form of a list.
>>>a=set([1,2,3])
>>>print(a)
{1,2,3}
Whereas you're not passing the string in list,
>>>a=set('FG')
>>>print(a)
{'F','G'}
so python interprets both of them differently.
If you pass the string as a list, the result would be similar to that of integer.
>>> a=set(['FG'])
>>> print(a)
{'FG'}
set() takes iterables as input.
The set constructor takes an iterable and adds each element of the iterable object to the set. So when you construct the set with the iterable list [1,2,3], you naturally end up with {1, 2, 3}.
A string is actually iterable:
for i in 'abc':
print(i)
Prints:
a
b
c
Iterating over a string returns each character of the string for each iteration. So when you construct a set with a string (which you can do because it is an iterable), you end up with a set where each character becomes a separate member of the set:
set('FG') -> {'F', 'G'}
But when you are creating a set by using a literal and not invoking a constructor, as in {'FG'}, you are just creating a set with a single member 'FG'.

going from word to number as in keys in a phone using a dictonary

Hello I have already done a through search before asking this question as I always do. I am trying to do use a dictionary to go from a written word to each individual letters corresponding letter on a phone key board using a dictionary in python. This is easy to do without a dictionary, but using a dictionary although faster to code is quite confusing to me. Help would be appreciated. My code so far is
def phone (word):
d = {'A''B''C':2,'D''E''F':3,'G''H''I':4,'J''K''L':5}
for i in range (len(word)):
word.split ()
return d[word]
the word I am trying to use is 'ADGJ' just as a test.
my errors that I am getting:
File "<pyshell#13>", line 1, in <module>
phone('ADGJ')
File "C:\Users\Christopher\Desktop\pratice.py", line 195, in phone
return d[word]
KeyError: 'ADGJ'
I have a key error I thought the word.split would take care of any issues but it doesn't. any suggestions?
thank you
I changed the code up a bit: I now have this:
def phone (word):
d = {'A':2, 'B':3}
word = word.split()
return d[word]
but I get a new error:
Traceback (most recent call last):
File "<pyshell#16>", line 1, in <module>
phone ('ABABBAA')
File "C:\Users\Christopher\Desktop\pratice.py", line 194, in phone
return d[word]
TypeError: unhashable type: 'list'
the word I am using just consits of 'ABBABABA' just because that is all I have defined in my dictionary since this is a test of understanding.
I guess I still need something to make the connection for the dictionary function thing to work but still trying to figure out what that is...
This is not valid Python
d = {'A''B''C':2,'D''E''F':3,'G''H''I':4,'J''K''L':5}
You would need to define each key, value pair
d = {
'A':2, 'B':2, 'C':2,
'D':3, 'E':3, ... etc
}
You can then convert the word into the corresponding digits
def getNums(word):
return ''.join(str(d[i]) for i in word)
>>> getNums('ADGJ')
'2345'
Your syntax is a little off; you can't let assignment in a dictionary fall through like in a switch statement.
Try this:
d = {'A':2,'B':2,'C':2,'D':3,'E':3,'F':3,'G':4,'H':4,'I':4,'J':5,'K':5,'L':5}
OK, so let me try to help you.
This is your current code:
def phone (word):
d = {'A':2, 'B':3}
word = word.split()
return d[word]
The first line defines your function signature, that means you've got a function called phone which takes a parameter called word. My first comment is: chose appropriate names for functions and variables. phone is not a "function", since a function is kind of an instruction or a command like thing, but never mind (letters_to_phonenumber would be better I think).
The second line defines a dictionary, which maps 'A' to 2, 'B' to '3'. That's OK for now.
The third line overwrites your word variable with the return value of the split() function, which is a method of the string class. Let's look up the documentation for this: https://docs.python.org/2/library/stdtypes.html#str.split
str.split([sep[, maxsplit]]):
Return a list of the words in the string, using sep as the delimiter string.
Since you obviously did not define a sep(arator), we have to figure out what the function will do. Reading further says:
If sep is not specified or is None, a different splitting algorithm is
applied: runs of consecutive whitespace are regarded as a single
separator, and the result will contain no empty strings at the start
or end if the string has leading or trailing whitespace. Consequently,
splitting an empty string or a string consisting of just whitespace
with a None separator returns [].
So it will look for whitespace within your string. You don't know what a whitespace is? Let's google: http://en.wikipedia.org/wiki/Whitespace_character
In computer science, whitespace is any character or series of
whitespace characters that represent horizontal or vertical space in
typography. When rendered, a whitespace character does not correspond
to a visible mark, but typically does occupy an area on a page.
OK, now we know, that whitespace is like space or tab etc. A string like "ABABBAA" does not contain any whitespace, so split() will obviously return only a list with exactly one item in it: the input string itself.
Let's fire up the python interpreter to check this (this is a common way of debugging):
>>> 'ABABBAA'.split()
['ABABBAA']
The next line in your code is return d[word]. So the function terminates here and returns an output value, namely d[word]. But what is the value of d[word]? Well, d is a dictionary (with the keys 'A' and 'B') and you try to find the value of the key ['ABABBAA']. But there is no such key in your dictionary d, let alone there is no way to create a key for a dictionary, since a key has to be a hashable object. What is a hashable object? Let's google: https://docs.python.org/2/glossary.html
hashable: An object is hashable if it has a hash value which never
changes during its lifetime (it needs a hash() method), and can be
compared to other objects (it needs an eq() or cmp() method).
Hashable objects which compare equal must have the same hash value.
Hashability makes an object usable as a dictionary key and a set
member, because these data structures use the hash value internally.
All of Python’s immutable built-in objects are hashable, while no
mutable containers (such as lists or dictionaries) are. Objects which
are instances of user-defined classes are hashable by default; they
all compare unequal (except with themselves), and their hash value is
their id().
OK, so 'A' would be hashable ;-) and any kind of number of string etc. but not a list, in this sense.
So what now? You have to find a way to somehow separate the letters in your input word. This can be easily done with slicing, or simply iterating over the string (in Python, strings are iterable):
for letter in word:
# this loop will iterate over word and assign each of its letters to
# the variable `letter`, which you can use in this scope
But how do we actually return the phone number? This will not work:
def phone (word):
d = {'A':2, 'B':3}
for letter in word:
return d[letter]
Why? Because it will stop at the first letter and terminate the function (remember the return statement?).
The way to go is to collect all the numbers and when we're done, simply put all together and return them. This is a common way to handle such problems. We first initialise a list, which we can manipulate in each for-iteration:
def phone (word):
d = {'A':2, 'B':3}
digits = []
for letter in word:
digits.append(d[letter])
return digits
Great! Looks better now:
>>> phone('ABA')
[2, 3, 2]
Now try to figure out how to return a real number instead of a list.
This is btw. kind of a basic workflow of a programmer. A lot of research and look-up in (API) documentation, solving puzzles and looking at few lines of code hours long. If you don't love it, you'll never become a programmer.

Python string get leading characters up to first comma

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 !

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