3

I'd like to print a 2D list in python without the commas.

Instead of printing

[[0,0,0,0,0,1,1,1,1,1,1],[0,0,0,0,0,0,1,1,1,1,0,0,0,1,1,0,0,1,1,0,1],[1,1,1] ... ]

I want to print

[[0 0 0 0 0 1 1 1 1 1 1 1] [0 0 0 0 0 0 1 1 1 1 0 0 0 1 1 0 0 1 1 0 1] [1 1 1] ... ]

Any insight on how I should do the same?

Thanks!

Aniruddh Chaturvedi
  • 623
  • 3
  • 9
  • 19

7 Answers7

5

Easy: just replace commas with spaces after converting to a string with repr.

def repr_with_spaces(lst):
    return repr(lst).replace(",", " ")

(This works for lists of integers, but not necessarily for anything else.)

Fred Foo
  • 355,277
  • 75
  • 744
  • 836
3

Here's a general solution. Convert a sequence into a string using a specified separator, and specified left and right bracketing characters.

lst = [[0,0,0,0,0,1,1,1,1,1,1],[0,0,0,0,0,0,1,1,1,1,0,0,0,1,1,0,0,1,1,0,1],[1,1,1]]

import sys
if sys.version_info[0] >= 3:
    basestring = str

try:
    from collections.abc import Iterable
except ImportError:
    from collections import Iterable


def str_seq(seq, sep=' ', s_left='[', s_right=']'):
    if isinstance(seq, basestring):
        return seq
    if isinstance(seq, Iterable):
        s = sep.join(str_seq(x, sep, s_left, s_right) for x in seq) 
        return s_left + s + s_right
    else:
        return str(seq)

print(str_seq(lst))

Why does the code have that isinstance(seq, basestr) check? Here is why:

How to check if an object is a list or tuple (but not string)?

Community
  • 1
  • 1
steveha
  • 74,789
  • 21
  • 92
  • 117
  • 2
    I'd probably use `isinstance(seq, collections.abc.Iterable)` instead of the try/except. – ecatmur Jul 31 '12 at 18:44
  • I don't see a `collections.abc.Iterable` but I do see a `collections.Iterable`... when I checked, `isinstance(x, collections.Iterable)` succeeded where `x` is a list, an iterator, or a generator. As long as you don't need to work with custom-made classes that don't bother to inherit from a suitable Python base type, the `isinstance()` check will work and should be noticeably faster. – steveha Jul 31 '12 at 18:54
  • `collections.abc` is Python 3. – ecatmur Jul 31 '12 at 19:05
  • @steveha: `isinstance(x, Iterable)` succeeds on any object that has an `__iter__` method. The `collections` ABCs use subclass hooks to customize `isinstance`. – Fred Foo Jul 31 '12 at 19:11
  • Wow, this is what I like about StackOverflow. Learning cool things like this. So basically if `for x in foo` would succeed, then `isinstance(foo, Iterable)` would return `True`? You guys have sold me on the idea. I'll edit the answer. – steveha Jul 31 '12 at 19:20
  • @larsmans -- do I understand correctly that the `collections.abc.Iterable` is smarter than the `collections.Iterable` that is in Python 2.x? Would it be possible, in Python 2.x, to "fool" the above code with a custom class that inherits only from `object` and defines its own methods so it works as an iterable? – steveha Aug 01 '12 at 00:07
  • @steveha: the 2.x version does this as well. Try defining a class with only an `__iter__` attribute, e.g. `class Foo(object): __iter__ = ()`. Then you'll find that `isinstance(Foo(), Iterable)` returns `True`. – Fred Foo Aug 01 '12 at 09:25
  • @larsmans -- Okay, I read up on this a little more and now I understand it. Python 2.6 introduced `collections.Iterable` and other abstract base classes in `collections`. The code I originally wrote would work for Python 2.5 and older, but for Python 2.6 and newer I like this much better. Anyone interested in abstract base classes should read the PEP: http://www.python.org/dev/peps/pep-3119/ – steveha Aug 01 '12 at 19:20
  • There is one case where this solution won't work, and the `try`/`except` would. In Python, if you implement `.__getitem__()` in your class, it is iterable even if you do not implement `.__iter__()`. I think I prefer the `Iterable` test anyway; if you want your class to be iterable, you should implement `.__iter__()`. Great discussion here: http://stackoverflow.com/questions/926574/why-does-defining-getitem-on-a-class-make-it-iterable-in-python – steveha Aug 06 '12 at 21:36
2

A general, safe and recursive solution, that works if the data contains commas:

def my_repr(o):
    if isinstance(o, list):
        return '[' + ' '.join(my_repr(x) for x in o) + ']'
    else:
        return repr(o)

The CPython implementation of list_repr uses essential this algorithm (using _PyString_Join).

ecatmur
  • 152,476
  • 27
  • 293
  • 366
  • This solution won't handle a tuple, an iterator, or a list-like object that doesn't inherit from `list`. I guess the question was just about a `list`, but it is easy in Python to solve the general problem; see my answer. – steveha Jul 31 '12 at 18:37
0

There's a couple ways:

your_string.replace(',',' ') 

' '.join(your_string.split(','))
Rob Volgman
  • 2,104
  • 3
  • 18
  • 28
0

Well, as a one-liner applied to array in variable "a":

print "[" + ' '.join(map(lambda row: "[" + ' '.join(map(str, row)) + "] ", a)) + "]"
Dan Stowell
  • 4,618
  • 2
  • 20
  • 30
0

You can use str.join():

lists = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]

def format_list(items):
    list_contents = ' '.join(str(it) for it in items) # convert contents to string too
    return '[{}]'.format(list_contents) # wrap in brackets

formatted = format_list(format_list(l) for l in lists)

ideone example: http://ideone.com/g1VdE

millimoose
  • 39,073
  • 9
  • 82
  • 134
0

Is

str([1,2],[3,4]).replace(","," ")

what you wanted?

log0
  • 10,489
  • 4
  • 28
  • 62
Prasanth
  • 5,230
  • 2
  • 29
  • 61