I want to rearrange a file alphabetically. Also I want the number to be printed next to the arranged letter.
e.g.:
a 4
c 5
e 6
f 2
here is my code:
f = open("1.txt","r")
r = f.read()
print(r)
r=r.split()
line=sorted(r)
for row in line:
print(line)
and here are the results I'm getting:
f 2
c 5
e 6
a 4
['2', '4', '5', '6', 'a', 'c', 'e', 'f']
['2', '4', '5', '6', 'a', 'c', 'e', 'f']
['2', '4', '5', '6', 'a', 'c', 'e', 'f']
['2', '4', '5', '6', 'a', 'c', 'e', 'f']
['2', '4', '5', '6', 'a', 'c', 'e', 'f']
['2', '4', '5', '6', 'a', 'c', 'e', 'f']
['2', '4', '5', '6', 'a', 'c', 'e', 'f']
['2', '4', '5', '6', 'a', 'c', 'e', 'f']
>>>
To get the pairs in sublists map str.split on the file object and call sorted on that:
with open("in.txt") as f:
print(sorted(map(str.split,f)))
in.txt:
e 6
c 5
f 2
a 4
Output:
[['a', '4'], ['c', '5'], ['e', '6'], ['f', '2']]
To sort a file alphabetically just getting the lines you would simply call sorted on the file object:
with open("test.txt") as f:
print(sorted(f))
If you want to format the output:
with open("test.txt") as f:
for sub in sorted(map(str.split,f)):
print("letter = {}, num = {}".format(*sub))
letter = a, num = 4
letter = c, num = 5
letter = e, num = 6
letter = f, num = 2
Also why you see ['2', '4', '5', '6', 'a', 'c', 'e', 'f'] is because calling split on .read splits all the data into a single list as split, splits on any whitespaces and when lexicographically comparing string digits to letters digits are considered lower so 2 < a, also beware when you are comparing string digits against each other as 11 > 100 = True as strings are compared character by character as 1 is considered greater than 0 100 would appear before 11 in your sorted list, when comparing digits cast to int.
If you want to have a max of three scores per user always keeping the most recent, you can use a deque with a maxlen of 3 and after the initial sort pickle the dict.
from csv import reader
from collections import deque, OrderedDict
import pickle
name, new_score = "foo",100
with open("test.txt") as f:
d = OrderedDict((name, deque(map(int,rest),maxlen=3)) for name, *rest in reader(sorted(f)))
print(d)
d[name].append(new_score)
print(d)
with open("my_data.pkl","wb") as out:
pickle.dump(d, out)
with open("my_data.pkl","rb") as out:
print(pickle.load(out))
test.txt:
homer,2
foo,1,2,3
bar,4,5,6
Output:
OrderedDict([('bar', deque([4, 5, 6], maxlen=3)), ('foo', deque([1, 2, 3], maxlen=3)), ('homer', deque([2], maxlen=3))])
OrderedDict([('bar', deque([4, 5, 6], maxlen=3)), ('foo', deque([2, 3, 100], maxlen=3)), ('homer', deque([2], maxlen=3))])
OrderedDict([('bar', deque([4, 5, 6], maxlen=3)), ('foo', deque([2, 3, 100], maxlen=3)), ('homer', deque([2], maxlen=3))])
Once sorted you just need to load to get the dict and dump after you have written.
You need to use readlines() instead of read() to get each line of the file as a seperate element of the list. Then a simple sort of the list will work.
f = open('1.txt','r')
# Use readlines isntead of of read to get an list of lines
lines = f.readlines()
print ''.join(lines)
# Now sort the list (default is by first letter
lines.sort()
print ''.join(lines)
Alternatively you could force the split function to use the end of line char '\n' instead of the default which is all white space. But now you will need to join the list back with the new line char ('\n') instead of an empty string.
f = open('1.txt','r')
lines = f.read()
lines = lines.split('\n')
print '\n'.join(lines)
# Now sort the list (default is by first letter
lines.sort()
print '\n'.join(lines)
Related
The inputs for the function are
a list of characters, eg: ['a','1']
length of combinations
The function should output a list of all possible character combinations as a list.
For example, for input ['a','1'] and length of 2, the function should output:
[['a','a'],
['a','1'],
['1','a'],
['1','1']]
and if the length is 3, the output should be:
[['a','a','a'],
['a','a','1'],
['a','1','a'],
['a','1','1'],
['1','a','a'],
['1','a','1'],
['1','1','a'],
['1','1','1']]
You can use itertools.product with the repeat parameter:
from itertools import product
data = ['a', '1']
n = 3
print(list(list(p) for p in product(data, repeat=n)))
This gives an output of:
[['a', 'a', 'a'], ['a', 'a', '1'], ['a', '1', 'a'], ['a', '1', '1'],
['1', 'a', 'a'], ['1', 'a', '1'], ['1', '1', 'a'], ['1', '1', '1']]
For example:
[['D', 'D', '-', '1', '.', '0'],['+', '2', '.', '0', 'D', 'D'],['D', 'D', 'D']]
This is:
D D -1.0
+2.0 D D
D D D
I want to extract the values, put in differents variables and know the line and column where the signal was (so i can put symbol that corresponds to the old value).
D D x
y D D
D D D
[['D', 'D', '-1.0'],['+2.0', 'D', 'D'],['D', 'D', 'D']]
Don't create a list of list. Take directly the lines from your file and split them with the help of regular expressions:
maze = []
for line in arq:
maze.append(re.findall('[-+][0-9.]+|\S', line)
import itertools
merged = list(itertools.chain(*list2d))
print [x for x in merged if not (x.isdigit() or x in '-+.')]
Use re.findall. The pattern [-+]?\d*\.\d+|\d+ is used to extract float values from a string.
import re
list2d = [['D', 'D', '-', '1', '.', '0'],['+', '2', '.', '0', 'D', 'D'],['D', 'D', 'D']]
lists = list()
for l in list2d:
s = ''.join(l)
matches = re.findall(r"D|[-+]?\d*\.\d+|\d+", s)
lists.append(matches)
print(lists)
# Output
[['D', 'D', '-1.0'], ['+2.0', 'D', 'D'], ['D', 'D', 'D']]
I'm not sure if this is what you want, could add more information in your description.
import csv
csv_file = open("maze.txt")
csv_reader = csv.reader(csv_file)
maze = []
for line in csv_reader:
for char in line:
maze.append(char.split())
print(maze)
# Output
[['D', 'D', '-1.0'], ['+2.0', 'D', 'D'], ['D', 'D', 'D']]
I have lists like:
['a', '2', 'b', '1', 'c', '4']
['d', '5', 'e', '7', 'f', '4', 'g', '6']
And I want to make a dictionary consist of keys as letters and values as numbers. I mean:
{'a': 2, 'b': 1, 'c': 4, 'd':5, 'e':7, 'f':4, 'g':6}
You can try:
>>> l = ['a', '2', 'b', '1', 'c', '4']
>>> it = iter(l)
>>> dict(zip(it, it))
{'a': '2', 'c': '4', 'b': '1'}
First you create an iterator out of the list. Then with zip of the iterator with itself you take pair of values from the list. Finally, with dict you transform these tuples to your wanted dictionary.
If you also want to do the string to number conversion, then use:
{x: int(y) for x, y in zip(it, it)}
EDIT
If you don't want to use zip then:
{x: int(next(it)) for x in it}
l = ['a', '2', 'b', '1', 'c', '4']
d = {k:v for k,v in zip(l[::2], l[1::2])}
Or if you want the numbers to be actual numbers:
l = ['a', '2', 'b', '1', 'c', '4']
d = {k:int(v) for k,v in zip(l[::2], l[1::2])}
Use float(v) instead of int(v) if the numbers have the potential to be floating-point values instead of whole numbers.
Without using any built-in functions:
l = ['a', '2', 'b', '1', 'c', '4']
d = {}
l1 = l[::2]
l2 = l[1::2]
idx = 0
while 1:
try:
d[l1[idx]] = l2[idx]
idx += 1
except IndexError:
break
You can split the lists into two, one containing the letters and the other containing the keys, with
key_list = old_list[::2]
value_list = old_list[1::2]
Then you can loop over the two lists at once with zip and you can make the dictionary.
I'm just having a bit of trouble getting my head around lists and tuples in python.
What I have is a list(? I think) and it needs to be converted to a tuple in the specific format given below? How would I go about this?
I have:
['A, B, C, D, e, f, g, h, i', '1, 2, 3, 4, 5, 6, 7, 8, 9',]
How can this be formatted to a tuple with a sub-tuple such as
[
('A', 'B', 'C', 'D', ('e', 'f', 'g', 'h', 'i')),
('1', '2', '3', '4', ('5', '6', '7', '8', '9')),
...
]
You can split each item in your list on the comma; here I am assuming you also always have a space after the comma:
result = []
for elem in inputlist:
elems = elem.split(', ')
elems[4:] = [tuple(elems[4:])]
result.append(tuple(elems))
The dance with tuple() and slice assignment is required to make it possible to build the outer tuple. The elems[4:] assignment here replaces the 5th-until-end part of the list with a list with just the one tuple.
If your strings contain commas without the whitespace or the whitespace is variable, you could use a split-and-strip strategy:
elems = [e.strip() for e in elem.split(',')]
Demo:
>>> inputlist = ['A, B, C, D, e, f, g, h, i', '1, 2, 3, 4, 5, 6, 7, 8, 9',]
>>> result = []
>>> for elem in inputlist:
... elems = elem.split(', ')
... elems[4:] = [tuple(elems[4:])]
... result.append(tuple(elems))
...
>>> result
[('A', 'B', 'C', 'D', ('e', 'f', 'g', 'h', 'i')), ('1', '2', '3', '4', ('5', '6', '7', '8', '9'))]
but the 5-9 elements in each 'list item' need to be in the nested tuple
Fixed size ? So what about:
import re
lst = ['A, B, C, D, e, f, g, h, i', '1, 2, 3, 4, 5, 6, 7, 8, 9',]
def prefix_by_four(lst):
return tuple(lst[:4]) + (tuple(lst[4:]),)
# ^^^^^^^^^^^^^^ ^ ^^
# make a tuple with the note how tuples are nested here:
# first 4 items make a tuple of one element `( ... ,)`
# containing a tuple with the remaining items
result = [ prefix_by_four(re.split(r',\s*',item)) for item in lst ]
# ^^^^^^
# split on `,` followed by
# zero or more spaces
from pprint import pprint
pprint(result)
Producing:
[('A', 'B', 'C', 'D', ('e', 'f', 'g', 'h', 'i')),
('1', '2', '3', '4', ('5', '6', '7', '8', '9'))]
Here I used an "helper function" to do the grouping. A lambda expression would have been possible, but less readable, I think.
The data I load with the below code will end up in the following format:
new_list = [['1', '100', 'A', 'B,A'], ['2', '200', 'A', 'T'],
['3', '200', 'H', 'A,C'], ['4', '300', 'W', 'T'],
['5', '400', 'I', 'BABA,ABB'], ['6', '500', 'Q', 'LP,AL']]
What I want to achieve is sorting the last column alphabetically changing the list to:
new_list = [['1', '100', 'A', 'A,B'], ['2', '200', 'A', 'T'],
['3', '200', 'H', 'A,C'], ['4', '300', 'W', 'T'],
['5', '400', 'I', 'ABB,BABA'], ['6', '500', 'Q', 'AL,LP']]
However I don't know how to sort only a specified index in this list.
Should I split the last column on ,?
Sample data:
# Data
# I
# don't
# need
1 100 982 A B,A 41
2 200 982 A T 42
3 200 982 H C 43
4 300 982 W T 43
5 400 982 I BABA,ABB 44
6 500 982 Q LP,AL 44
Loading the data:
filename = 'test.txt'
new_list = []
readFile = open(filename, 'r')
lines = readFile.readlines()
for line in lines:
if not line[0].startswith('#'):
linewords = line.split()
new_list.append([linewords[0],
linewords[1],
linewords[3],
linewords[4]])
split it on ",", then sort, then join the list :
new_list.append([linewords[0],
linewords[1],
linewords[3],
",".join(sorted(linewords[4].split(",")))])
first split, then sort, last join. there may be more than one blank space, you can use regex split.
import re
p = re.compile(' +')
for line in lines:
if line.startswith('#'):
continue
linewords = p.split(line)
lastword = linewords[4].split(',')
lastword.sort()
new_list.append([linewords[0],linewords[1],linewords[3],','.join(lastword)])
try:
def sort_last(inner_list):
last = inner_list[-1].split(',')
last.sort()
last = ','.join(last)
return inner_list[:-1] + [last]
new_list = [sort_last(l) for l in new_list]
[x[:-1]+[','.join(sorted(x[-1].split(',')))] for x in new_list]
Try this
list2 = []
for level1 in new_list:
_temp = []
for level2 in level1:
if "," in level2:
_temp.append(sorted(level2.split(",")))
else:
_temp.append(level2)
list2.append(_temp)
print list2