How to create a new dictionary where all keys and values are converted to string type? If string length is more than 5 symbols it must be excluded from the answer (both the key and value)
My code now looks like this:
file1data = {"1":"2",2:5,"12dade":-1,"1231":14,"-2":7}
key_values = file1data.items()
new_dictionary = {str(key):str(value) for key, value in key_values}
print((str(new_dictionary)))
It can covert all values and keys to a string type, but not detect if length is more than 5.
For example if is given this dictionary: {"1":"2",2:5,"12dade":-1,"1231":14,"-2":7}
The result should be: {"1":"2","2":"5","1231":"14","-2":"7"}
Add if statement inside dict comprehension like so
file1data = {"1": "2", 2: 5, "12dade": -1, "1231": 14, "-2": 7}
key_values = file1data.items()
new_dictionary = {str(key): str(value) for key, value in key_values if len(str(key)) <= 5 and len(str(value)) <= 5}
print((str(new_dictionary)))
A simple way to do it is to iterate through the keys of the dictionary and check if you should delete it or not if yes add it to a list and delete it later
file1data = {"1":"2",2:5,"12dade":-1,"1231":14,"-2":7}
delete = list()
for key in file1data:
if len(str(key)) > 5:
delete.append(key)
for i in delete:
del file1data[i]
I know that it is not the most compact way to do it but it works
Use a comprehension:
d = {'1': '2', 2: 5, '12dade': -1, '1231': 14, '-2': 7}
out = {k: v for k, v in d.items() if len(str(k)) <= 5 and len(str(v)) <= 5}
print(out)
# Output
{'1': '2', 2: 5, '1231': 14, '-2': 7}
Without converting to string twice:
{sk: sv
for k, v in file1data.items()
if len(sk := str(k)) <= 5
if len(sv := str(v)) <= 5}
You can achieve this by using an if clause inside of the dictionary comprehension, like so:
file_data = {"1": "2", 2: 5, "12dade": -1, "1231": 14, "-2": 7}
filtered_file_data = {str(key): str(value) for key, value in file_data.items() if len(str(key)) <= 5 and len(str(value)) <= 5}
print(filtered_file_data)
Output:
{'1': '2', '2': '5', '1231': '14', '-2': '7'}
dict={a:qwertyuiop} dict1={a:qw,b:er,c:ty,d:ui,e:op}
I want to create dict 1 from dict with splitting the value with length of 2
I have tried
value1=dict.value()
value2=value1.split(2)
It does not accept integer and I obviously using the wrong function, I have searched on the net but could not find it, which function should I use?
# Defining variables
d = {'a': 'abcde', 'b': 'cdefghi'}
n = 2
# One-Liner:
d1 = dict([(i + j*len(d), word) for j, key in enumerate(d.keys()) for i, word in enumerate([d[key][i:i+n] for i in range(0, len(d[key]), n)])])
print(d1)
# Normal code
d2 = dict()
for j, key in enumerate(d.keys()): # Enumerating threw the keys
for i, word in enumerate([d[key][i:i + n] for i in range(0, len(d[key]), n)]): # Enumerating threw n-characters at a time
d2[i + j*len(d)] = word # Assigning to the right key with math
print(d2)
One downside to this code is that we are losing the keys,
This has to be done in order to keep having only one key per value.
Output for d1: {0: 'ab', 1: 'cd', 2: 'cd', 3: 'ef', 4: 'gh', 5: 'i'}
Output for d2: {0: 'ab', 1: 'cd', 2: 'cd', 3: 'ef', 4: 'gh', 5: 'i'}
This function allows you to do exactly that, and gives you the choice of integer keys or letter keys by typing int or chr as the third function argument:
def ds(d,n,v=chr):
return({v(int(y/n)+[96 if v==chr else 0][0]):"".join([str(d[z]) for z in d])[y-n:y] for y in range(n,len("".join([d[z] for z in d]))+n,n)})
This works by first iterating through the dictionary values and returning the value of each key (in the str(d[z]) for z in d). The function then joins the list of string values together, (the "".join part), and then parses through the length that string (the for y in range(...) part) and returns a dictionary with values split every nth time.
Examples:
a=ds(myDictionary,2) #split every second character (string keys)
print(a)
#{'a': 'qw', 'b': 'er', 'c': 'ty', 'd': 'ui', 'e': 'op'}
b=ds(myDictionary,3,int) #split every third (integer keys)
print(b)
#{1: 'qwe', 2: 'rty', 3: 'uio', 4: 'p'}
c=ds(myDictionary,56,char) #split every fifty-sixth (string keys)
print(c)
#{'a': 'qwertyuiop'}
Also, no outside modules required! This is all built-in stuff.
I have multiple strings like:
0000NNN
000ANNN
I wish to get a dictionary which has the position of the character in each string as the key and the count of its respective 0 as the value (If the character is NOT 0, it can be ignored). So for the above strings, the output would be:
1:2
2:2
3:2
4:1
5:0
6:0
7:0
So far i tried this:
ctr=1
my_dict={}
for word in string_list:
for letter in word:
if letter == "0":
if ctr not in my_dict.keys():
my_dict[ctr]=1
else:
my_dict[ctr]+=1
else:
pass
print(my_dict)
What am I doing wrong as the output is not correct?
Looks like you never increases and resetting ctr and not adding my_dict[ctr]=0 for 5,6,7. Something like this should work:
string_list = ['0000NNN','000ANNN']
my_dict={}
for word in string_list:
ctr=1 #Moved
for letter in word:
if letter == "0":
if ctr not in my_dict.keys():
my_dict[ctr]=1
else:
my_dict[ctr]+=1
else:
my_dict[ctr]=0 #Added
ctr+=1 #Added
print(my_dict) #{1: 2, 2: 2, 3: 2, 4: 0, 5: 0, 6: 0, 7: 0}
You can use collections.Counter in the following way:
>>> Counter(i for string in strings for i, c in enumerate(string, start=1) if c == '0')
Counter({1: 2, 2: 2, 3: 2, 4: 1})
You're not incrementing ctr, so ctr == 1 always. But, that alone won't get you what you want. Right now, you're counting all of the '0's in all of your words and storing them in the dictionary key '1'.
Instead, you want to keep track of the position and the count separately.
my_dict = {}
for pos in range(7): # assuming your "words" are the same length - 7 chars
my_dict[pos] = 0
for word in string_list:
if word[pos] == '0':
my_dict[pos] += 1
You could use zip() like this.
s = ["0000NNN", "000ANNN"]
d = {}
for i,v in enumerate(zip(s[0], s[1]),1):
d[i] = v.count('0')
print(d)
{1: 2, 2: 2, 3: 2, 4: 1, 5: 0, 6: 0, 7: 0}
Something along the following lines should point you in the right direction:
strings = ["0000NNN", "000ANNN"]
d = {i+1: sum(s[6-i] != "0" for s in strings) for i in range(7)}
# {1: 2, 2: 2, 3: 2, 4: 1, 5: 0, 6: 0, 7: 0}
The 6 six would be length-1 in the general case.
I get some data like this
A=['A,1','A,2','A,4','A,5','B,2','B,3','B,4','B,5','C,2','C,20','C,200','C,2']
I want to have a result like this,This means the the name,the min number, the max number.I have 1 million data like this.
'A,1,5','B,2,5','C,2,200'
I tried in this way:
A=['A,1','A,2','A,4','A,5','B,2','B,3','B,4','B,5','C,2','C,20','C,200','C,2']
B=[]
C=[]
for r in A:
B.append(r.split(',')[0])
B_set=list(set(B))
catagory_number=range(0,len(B_set),1)
for j in catagory_number:
numbers = []
for r in A:
if B_set[j]==r.split(',')[0]:
numbers.append(r.split(',')[1])
print numbers
As you can see, it do not work, I get problem to get data together.
['1']
['1', '2']
['1', '2', '4']
['1', '2', '4', '5']
['2']
['2', '20']
['2', '20', '200']
['2', '20', '200', '2']
['2']
['2', '3']
['2', '3', '4']
['2', '3', '4', '5']
Any suggestions?
You could iterate over your list and derive the min and max values using an OrderedDict. At the end you can re-create the string as I show, but actually you might be better off keeping the dictionary data structure (depends what you want to do next):
import collections
def sol(lst):
d = collections.OrderedDict()
for item in lst:
key, value = item.split(',')
value = int(value)
if key in d:
if value < d[key][0]:
d[key][0] = value
elif value > d[key][0]:
d[key][1] = value
else:
d[key] = [value, value] # key = letter; value = [min, max]
return ['{},{},{}'.format(key,*values) for key,values in d.items()] # in Python 2 use key,value[0],value[1]
Example:
my_lst = ['A,1','A,2','A,4','A,5','B,2','B,3','B,4','B,5','C,2','C,20','C,200','C,2']
print(sol(my_lst))
# ['A,1,5', 'B,2,5', 'C,2,200']
A defaultdict with a list as default value could help you a lot:
>>> from collections import defaultdict
>>> data = defaultdict(list)
>>> data['A']
[]
>>> data['A'].append(1)
>>> data['A'].append(2)
>>> data['B'].append(3)
>>> data
defaultdict(<type 'list'>, {'A': [1, 2], 'B': [3]})
It's probably what you wanted to write with set and multiple loops. defaultdict is a standard structure and should be fast enough, even with many values.
Here's a beginning of a solution with this data structure:
from collections import defaultdict
data = defaultdict(list)
A = ['A,1','A,2','A,4','A,5','B,2','B,3','B,4','B,5','C,2','C,20','C,200','C,2']
for couple in A:
letter, number = couple.split(',')
data[letter].append(int(number))
print(data)
# defaultdict(<type 'list'>, {'A': [1, 2, 4, 5], 'C': [2, 20, 200, 2], 'B': [2, 3, 4, 5]})
For each letter in A, you now have a list of corresponding values. It shouldn't be too hard to extract min and max and write the desired list.
you can try this:
letter=[]
number=[]
A=['A,1','A,2','A,4','A,5','B,2','B,3','B,4','B,5','C,2','C,20','C,200','C,2']
for couple in A:
a, b = couple.split(',')
if a not in letter:
letter.append(a)
number.append([b])
else:
ind=letter.index(a)
number[ind].append(b)
B=[]
i=0
while i<len(letter):
B.append(letter[i]+","+str(min(number[i]))+","+str(max(number[i])))
i+=1
print (B)
['A,1,5', 'B,2,5', 'C,2,200']
You can achieve what you intented to do using groupby from itertools module and using list comprehension like this example:
from itertools import groupby
A = ['A,1','A,2','A,4','A,5','B,2','B,3','B,4','B,5','C,2','C,20','C,200','C,2']
sub_final = (sorted(list(v), key = lambda x: int(x.split(",")[1])) for _,v in groupby(sorted(A), lambda x: x[0]))
final = ["{0},{1}".format(k[0],k[-1].split(',')[-1]) for k in sub_final]
print(final)
Output:
['A,1,5', 'B,2,5', 'C,2,200']
Might not be the fastest but I think this is easy to read. Can't offer formatting since I'm using Python 3.4.
A=['A,1','A,2','A,4','A,5','B,2','B,3','B,4','B,5','C,2','C,20','C,200','C,2']
summary = {}
for a in A:
k, v = a.split(',')
v = int(v)
if k in summary:
summary[k] = (min(v, summary[k][0]), max(v, summary[k][1]))
else:
summary[k] = (int(v), int(v))
for k in sorted(summary.keys()):
print (k, summary[k])
Basic idea is to split the list on the basis of it's headers i.e. A, B, C...and find the min and max for each of them. Below is one way to do so:
#!/usr/bin/python
A=['A,1','A,2','A,4','A,5','B,2','B,3','B,4','B,5','C,2','C,20','C,200','C,2']
headerList = []
assoNumList = []
finalList = []
# Iterate over the list to obtain the headers i.e. A,A,A,A,A,B,B,B....C,...
for a in range(len(A)):
header = A[a][0]
headerList.append(header)
# Convert the list into a set to get distinct headers i.e. A,B,C..
headerSet = set(headerList)
uniqueHeaderList = list(headerSet)
# Iterate over the unique header list to get all numbers associated
# with each header. Apply min and max functions over the number set
# to get the Header wise Min and Max numbers.
for i in range(len(uniqueHeaderList)):
for a in range(len(A)):
if(A[a][0] == uniqueHeaderList[i]):
assoNum = A[a][2:]
assoNumList.append(assoNum)
header = A[a][0]
result = header+","+min(assoNumList)+","+max(assoNumList)
finalList.append(result)
del assoNumList[:]
print(sorted(finalList))
#Output: ['A,1,5','B,2,5','C,2,200']