I need to convert a single input string into a dictionary - string

I need to convert a single input string into a dictionary with its place indices as keys and the letters as values in python. But I'm stuck here. Any help will be appreciated.
r = list("abcdef")
print (r)
for index,char in enumerate(r,0):
indd = str(index)
print(indd)
abc = indd.split(",")
list2 = list(abc)
d = dict(zip(list2,r))
print(d)

This is one approach using range.
Demo:
r = list("abcdef")
d = {}
for i in range(len(r)):
d[i] = r[i]
print(d)
Output:
{0: 'a', 1: 'b', 2: 'c', 3: 'd', 4: 'e', 5: 'f'}
Or a simpler approach using dict().
r = list("abcdef")
d = dict(zip(range(len(r)), r))
print(d)

You have a string abcdef.
First make a list of tuples having first element of tuple as place index and second element of the tuple as the letter at that index. This can be done in this way:
tuples = list(enumerate("abcdef"))
Now, using the dictionary constructor, convert this list of tuples to a dictionary as given below:
dict(tuples)
Demo:
>>> dict(list(enumerate("abcdef")))
{0: 'a', 1: 'b', 2: 'c', 3: 'd', 4: 'e', 5: 'f'}

Related

How to group pandas series by values and return dict of list of indices for those values, without explicitly transforming the series first?

I have a pandas series that looks like this:
import numpy as np
import string
import pandas as pd
np.random.seed(0)
data = np.random.randint(1,6,10)
index = list(string.ascii_lowercase)[:10]
a = pd.Series(data=data,index=index,name='apple')
a
>>>
a 5
b 1
c 4
d 4
e 4
f 2
g 4
h 3
i 5
j 1
Name: apple, dtype: int32
I want to group the series by its values and return a dict of of list of indices for those values i.e. this result:
{1: ['b', 'j'], 2: ['f'], 3: ['h'], 4: ['c', 'd', 'e', 'g'], 5: ['a', 'i']}
Here is how I achieve that at the moment:
b = a.reset_index().set_index('apple').squeeze()
grouped = b.groupby(level=0).apply(list).to_dict()
grouped
>>>
{1: ['b', 'j'], 2: ['f'], 3: ['h'], 4: ['c', 'd', 'e', 'g'], 5: ['a', 'i']}
However, it does not feel particularly pythonic to explicitly transform the series first so that I can get to the result. Is there a way to do this directly by applying a single function (ideally) or combination of functions in one line to achieve the same result?
Thanks!
You can use the groupby function and apply a lambda expression to it in order to get the desired result in one line:
grouped = a.groupby(a.values).apply(lambda x: list(x.index)).to_dict()
Alternatively, you could use the following:
grouped = dict(a.groupby(a.values).apply(lambda x: x.index.get_level_values(0)))
grouped = dict(a.groupby(a.values).apply(lambda x: x.index.tolist()))

Convert number to letters using dictionary in Python

I have input that provides a number and a sequence of distinct letters (upper/lowercase).
The program generates a dictionary for provided sequence of letters and the number should be converted using into letters using values from dictionary.
For example, I have following input:
Convert 49036 using fFeEdDcCbBaA.
The dictionary created for this sequence of letters is:
numberkey = {500000: 'f', 100000: 'F', 50000: 'e', 10000: 'E', 5000: 'd', 1000: 'D', 500: 'c', 100: 'C', 50: 'b', 10: 'B', 5: 'a', 1: 'A'}
The output of the conversion should be this:
EeDEBBBaA
Roman number conversion rules applies.
The output I'm getting so far is not correct:
EEEEdDDDDBBBaA
Would appreciate any help. Thanks.
Here's a simple and generalised approach, based on the Roman Numeral concept.
n = 49036
numberkey = {500000: 'f', 100000: 'F', 50000: 'e', 10000: 'E', 5000: 'd', 1000: 'D', 500: 'c', 100: 'C', 50: 'b', 10: 'B', 5: 'a', 1: 'A'}
x = list(numberkey.items())
x.sort()
new_base = [] #to get special symbols for 4's and 9's
for i in range(len(x)-1):
if x[i][0] < (x[i+1][0]/2):
new_base.append((x[i+1][0]-x[i][0], x[i][1]+x[i+1][1]))
if (str(x[i][0]).find("10")==0) and numberkey.get(x[i][0]//10, None):
num = numberkey[x[i][0]//10]
new_base.append((x[i][0]-(x[i][0]//10), num+x[i][1]))
x += new_base
x.sort()
ans = ""
i = len(x)-1
while n and i>=0:
count = n//x[i][0]
if count:
ans += count*x[i][1]
n -= count*x[i][0]
i -= 1
print(and) #EeDEBBBaA

Counting frequency of element in a list and joining them

I have a list of list. I want to obtain the frequency of element in the inner list and concatenate that with the element in the outer list.
aa =['a', ['b', 'b', 'b', 'b', 'd', 'd']]
I try to use Counter to get the frequency of occurrence of each element in the inner list as :
from collections import Counter
Counter(aa[1])
It gives:
Counter({'b': 4, 'd': 2})
I want to concatenate this with the outer list element and obtain as follows:
'ab4d2'
I can also iterate through the Counter and get key, value in a list:
y = []
for k, v in surr.items():
y.append(str(k) + str(v))
Output: ['O4', 'Sb2']
There are many answers to get the frequency of occurrence but I did not find any which does this (the problem is joining with outer 'a' in an efficient way) . Could anyone please help me on this. Thanks in advance.
You can use a generator expression with str.join:
aa[0] + ''.join('%s%d' % t for t in Counter(aa[1]).items())
Given aa = ['a', ['b', 'b', 'b', 'b', 'd', 'd']], this returns:
ab4d2

Function doesn't change value, when applied to nested list

I have a function which iterates over list of lists. If it finds the value, which is a list itself, it should create a string from this value and insert it instead of the original one:
def lst_to_str(lst):
for x in lst:
for y in x:
i = 0
if type(y) == list:
x[i] = ",".join(y)
i +=1
return lst
The problem is, when I apply this function to pd.DataFrame column
df['pdns'] = df['pdns'].apply(lambda x: lst_to_str(x))
It returns me the original nested list:
[['a', 'b', 'c', 'd'], ['a1', 'b1', 'd1', 'c1'],['a2', 'b2', 'c2', ['d2_1', 'd2_2']]]
Instead of:
[['a', 'b', 'c', 'd'], ['a1', 'b1', 'd1', 'c1'],['a2', 'b2', 'c2', 'd2_1, d2_2']]
Your code is wrong. In your function definition, you're not making any change to 1st and in the end you return 1st. You're checking some condition and then you change the value of your counter (x). Correct this problem and try again

Calling a list of DataFrame index with index key value

df = pd.DataFrame([[3,3,3]]*4,index=['a','b','c','d'])
While we can extract a copy of a section of an index via specifying row numbers like below:
i1=df.index[1:3].copy()
Unfortunately we can't extract a copy of a section of an index via specifying the key (like the case of df.loc method). When I try the below:
i2=df.index['a':'c'].copy()
I get the below error:
TypeError: slice indices must be integers or None or have an __index__ method
Is there any alternative to call a subset of an index based on its keys? Thank you
Simpliest is loc with index:
i1 = df.loc['b':'c'].index
print (i1)
Index(['b', 'c'], dtype='object')
Or is possible use get_loc for positions:
i1 = df.index
i1 = i1[i1.get_loc('b') : i1.get_loc('d') + 1]
print (i1)
Index(['b', 'c'], dtype='object')
i1 = i1[i1.get_loc('b') : i1.get_loc('d') + 1]
print (i1)
Index(['b', 'c', 'd'], dtype='object')
Alternative:
i1 = i1[i1.searchsorted('b') : i1.searchsorted('d') + 1]
print (i1)
Index(['b', 'c', 'd'], dtype='object')
Try using .loc, see this documentation:
i2 = df.loc['a':'c'].index
print(i2)
Output:
Index(['a', 'b', 'c'], dtype='object')
or
df.loc['a':'c'].index.tolist()
Output:
['a', 'b', 'c']

Resources