7

I want to store a list of integers as a field in my model. As there is no field provided for this by default in Django, I am doing it by using a CommaSeparatedIntegerField called x. In my view, I then take this string and create a list of integers from it. When a model instance is created with parameter n, I want x to be set to length n, with each element being set to zero.

Here's the model:

class Foo(models.Model):
    id = models.IntegerField(default = 0)
    x = models.CommaSeparatedIntegerField(max_length = 10)

@classmethod
def create(cls, _id, n):
    user = cls(id = _id)
    user.class_num_shown = '0,' * n

Then I create an instance:

f = Foo.create(1, 4)
f.save()

And load it from the database and convert the string into a list:

f = Foo.objects.get(id = 1)
x_string = f.x
x_list = x_string.split(',')
print x_list

But this outputs [u'0,0,0,0,'] rather than what I want, which would be [0,0,0,0]. How can I achieve my desired output?

Karnivaurus
  • 22,823
  • 57
  • 147
  • 247
  • 2
    Not sure why this is happening, but If i were to guess, you are doing a `.split()` instead of a `.split(',')` .Alternatively, `ast.literal_eval('0, 0, 0, 0')` gives you the desired result. – karthikr Jul 03 '14 at 14:44

2 Answers2

5

The separator argument for split() is not a list of different characters to split on, but rather the entire delimiter. Your code will only split occurrences of "comma space".

Further, if you want integers instead of substrings, you need to do that conversion.

Finally, because you have a trailing comma, you need to filter empty results from your split.

>>> data = '0,0,0,0,'
>>> values = [int(x) for x in data.split(',') if x]
>>> values
[0, 0, 0, 0]
FogleBird
  • 74,300
  • 25
  • 125
  • 131
  • Thanks, that works. But please can you explain the syntax of `[int(x) for x in data.split(',') if x]`? What does the `if x` mean? – Karnivaurus Jul 03 '14 at 14:44
  • 1
    They are called [`list_comprehensions`](https://docs.python.org/2/tutorial/datastructures.html#list-comprehensions) – karthikr Jul 03 '14 at 15:20
  • This may sound redundant, but `if x` will check if x is `True`. x in this case is a string, and a string in Python is `False` when empty and `True` otherwise. – RJT Jul 03 '14 at 15:29
  • @RJT - That is not entirely true. `if x` is looking for the truth value. Basically, it does `bool(x) == True` - and in this case, non-empty strings have a truth value of `True` - So it is perfectly valid. This is requred because the string ends with a `,` and you cannot do an `int(None)` – karthikr Jul 03 '14 at 15:40
  • That's what I meant, but I simplified it too much. Thanks for the clearer answer. – RJT Jul 03 '14 at 16:44
  • @karthikr: In this case you cannot do an `int('')` – FogleBird Jul 03 '14 at 17:03
4
values = map(int, '0,1,2,3,'.rstrip(',').split(','))
Eugene Soldatov
  • 9,755
  • 2
  • 35
  • 43