从列表或元组中访问数据并清理它

时间:2017-04-21 07:01:07

标签: python list sqlite tuples

这是一个关于数据清理以及如何与列表和元组进行交互的概念性问题,我不确定如何解释,但如果我可以解决它,我在概念上可以更好地使用python。

这是:(使用python 3和sqlite3)

我有一个带有日期列的SQLite数据库,其中的文本格式为MM-DD-YY 24:00。在DB Browser中查看时,文本看起来很好。但是,在Python中使用fetchall()时,代码会以' MM-DD-YY \ xa0'的格式打印日期。我想从代码中清除\ xa0,我尝试了一些代码,这些代码是我认为我应该做的以及我在这里阅读的另一篇文章的组合。这是代码:

 print(dates)
 output [('MM-DD-YY\xa0',), ('MM-DD-YY\xa0',)etc.blahblah] i just typed this in here 
 to show you guys the output 
 dates_clean = []
 for i in dates:
      clean = str(i).replace(u'\xa0', u' ')
      dates_clean.append(clean)

现在当我打印dates_clean时,我得到:

 ["('MM-DD-YY\xa0',)", "('MM-DD-YY\xa0',)"etc]

所以现在你可以看到当我试图清理它时,它做了我想要它做的事情,但现在它最初包含的实际元组已成为文本本身的一部分并包含在另一个元组中。因此,当我使用UPDATE语句将此列表写回SQLite时。所有日期值都包含在元组中。

它让我感到沮丧,因为我一直面临着这样的问题,我想在列表或元组内部编辑某些内容并让新值替换旧值而不是保留所有字符说它是一个元组,使它们只是文本。对不起,如果这让我感到困惑,就像我说的那样难以解释。在尝试清理时,我总是把数据弄脏了。

如何有效清理列表和元组中的数据的任何见解将不胜感激。我觉得我对访问元组或访问元组内部的区别感到困惑。如果你可以建议我所处理的概念性问题的名称,那么我也可以自己做更多的研究。

谢谢!

2 个答案:

答案 0 :(得分:1)

通过在元组上调用str() 使输出,无论是在一次打印整个数组时是隐式还是在尝试“清理”它时显式地。

见(python3):

>>> print("MM-DD-YY\xa024:00")
MM-DD-YY 24:00

但:

>>> print(("MM-DD-YY\xa024:00",))
('MM-DD-YY\xa024:00',)

这是因为tuple.__str__在内容上调用repr,转义过程中的非ascii字符。

但是,如果将元组元素作为单独的参数打印,结果将是正确的。因此,您希望将打印替换为:

for row in dates:
    print(*row)

*扩展元组以分隔参数。由于这些是字符串,因此它们将按原样打印:

>>> row = ("MM-DD-YY\xa023:00", "MM-DD-YY\xa024:00")
>>> print(*row)
MM-DD-YY 23:00 MM-DD-YY 24:00

如果您愿意,可以添加分隔符

>>> print(*row, sep=', ')
MM-DD-YY 23:00, MM-DD-YY 24:00

...或者你可以格式化它:

>>> print('from {0} to {1}'.format(*row))
from MM-DD-YY 23:00 to MM-DD-YY 24:00

我在这里再次使用*扩展元组以分隔参数,然后只为第0个成员{0},第一个为{1},第二个为{2}等。 (如果您不需要更改订单,也可以使用{}作为下一个,但是给索引更清楚。)

好的,现在如果你真的需要摆脱不间断的空间,替换是正确的工具。您只需将它应用于元组的每个元素。有两种方法:

  1. 明确的解构;当元素数量固定时应该适用(应该是;它是一行已知查询):

    假设:

    >>> row = ('foo', 2, 5.5)
    

    你可以解构它并构建一个新的元组:

    >>> (a, b, c) = row
    >>> (a.replace('o', '0'), b + 1, c * 2)
    ('f00', 3, 11.0)
    

    这使您可以对每列进行不同的转换。

  2. 映射;当你想对所有元素进行相同的转换时适用:

    假设:

    >>> row = ('foo', 'boo', 'zoo')
    

    您只需将生成器理解包装在tuple构造函数中:

    >>> tuple(x.replace('o', '0') for x in row)
    ('f00', 'b00', 'z00')
    
  3. 另一方面,SQLite有一些日期和时间函数,他们希望时间戳采用严格的IS8601格式,即%Y-%m-%dT%H:%M:%S(最后选择%z;使用strftime格式;在TR#35格式中,它是YYYY-MM-ddTHH-mm-ssxx))。

答案 1 :(得分:0)

在您的情况下,dates实际上是一个元组列表,每个元组包含一个字符串元素。日期字符串末尾的,是您识别单个元素元组的方式。

你需要处理元组中每个元素的for循环,而不是元组本身。有点像:

for i in dates: 
     date = i[0] 
     clean = str(date).replace('\xa0', '') 
     dates_clean.append(date)

我不确定这是您在数据库中操作数据的实际问题的最佳解决方案,但应该回答您的问题。

编辑:另外,请参阅Jan关于unicode字符串和python 2与python 3的回复。