Python – Converting Ruby to Python

python, regex, ruby

I'm trying to convert my ruby script to python. I'm not very familiar with python so I am getting a TypeError.

printer.rb

Lease = Struct.new(:property, :renter)lease_list = []File.open('input.txt').readlines.each do |line|  p, r = line.split(' - ')  lease_list << Lease.new(p.tr('#', ''), r)end# sort by decimal valuelease_list.sort_by { |m| m.property.scan(/\d+/)[0].to_i }.each do |lease|  puts "\##{lease.property} - #{lease.renter}"end

printer.py

import reclass Lease:  def __init__(self, renter=None, unit=None):    self.renter = renter    self.property = unitlease_list = []import syslines = open('input.txt', 'r')for line in lines:    l, m = line.split(' - ')    lease_list.append(Lease(l,m))lines.close()print lease_list.sort(key=lambda lease: re.split(r"\d+", lease.property))

python error

Traceback (most recent call last):   File "printer.py", line 16, in<module>    print lease_list.sort(key=lambda str: re.split(r"\d+", str))   File "printer.py", line 16, in <lambda>    print lease_list.sort(key=lambda str: re.split(r"\d+", str))   File"/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/re.py",line 171, in split    return _compile(pattern, flags).split(string, maxsplit) TypeError: expected string or buffer

Best Solution

The problem is here:

print lease_list.sort(key=lambda str: re.split(r"\d+", str))

The str name [edit: see Question edit history], which you generally shouldn't use as a name, even as throwaways) which is assigned values contained in your list and consequently passed to re.split() is an object of type Lease:

lease_list.append(Lease(l,m))

This isn't accepted as an argument to re.split it likes munching on strs. hence the TypeError. Lease has two attributes which are strs after the line.split(' - '):

self.renter = renterself.property = unit

Use one of these in re.split() (whichever is required for your use-case) with:

print lease_list.sort(key=lambda obj: re.split(r"\d+", obj.renter))

or:

print lease_list.sort(key=lambda obj: re.split(r"\d+", obj.property))

Forgot to mention, sorting a list with list.sort will return None since it sorts the list in place, printing the value here has no use.