6

Does Python have any data types for FIFO buffering of strings? I created something (below) but suspect I'm reinventing the wheel.

class Buffer(list):
    def __init__(self):
        super(Buffer, self).__init__()

    def put(self, nlmsg):
        for c in nlmsg: self.append(c)

    def peek(self, number):
        return "".join( [self[i] for i in range(number)] )

    def get(self, number):
        return "".join( [self.pop(0) for i in range(number)] )

Usage example:

>>> buf = Buffer()
>>> buf.put('abcdefg')
>>> buf
['a', 'b', 'c', 'd', 'e', 'f', 'g']
>>> buf.peek(4)
'abcd'
>>> buf
['a', 'b', 'c', 'd', 'e', 'f', 'g']
>>> buf.get(5)
'abcde'
>>> buf
['f', 'g']

I looked at Queue but when adding a str I would have to split each byte manually, else the entire str would become an item in the queue. Is there anything like this already out there?

3
  • 1
    Does StringIO do what you need? docs.python.org/library/io.html#io.StringIO Commented Feb 9, 2012 at 21:35
  • @ThomasK I hadn't looked at that. but at a glance it looks like it might not work since when reading off the front, it looks like i would have to shift the remaining data, or keep a pointer to where I'm reading in the string. (im kind of a newb, so i might be missing something) Commented Feb 9, 2012 at 21:43
  • A class wrapper is I good idea. I would inherit from str rather than list however. String already has slicing capabilities and it would save the cost of using join. timeit and see what works better :) Commented Feb 9, 2012 at 22:11

3 Answers 3

3

Using collections.deque it would be implemented as follows:

from collections import deque

class Buffer(deque):
    def put(self, iterable):
        for i in iterable:
            self.append(i)

    def peek(self, how_many):
        return ''.join([self[i] for i in xrange(how_many)])

    def get(self, how_many):
        return ''.join([self.popleft() for _ in xrange(how_many)])



buf = Buffer()
buf.put('abcdefg')
print buf
print buf.peek(4)
print buf
print buf.get(5)
print buf

Example output:

deque(['a', 'b', 'c', 'd', 'e', 'f', 'g'])
abcd
deque(['a', 'b', 'c', 'd', 'e', 'f', 'g'])
abcde
deque(['f', 'g'])
Sign up to request clarification or add additional context in comments.

Comments

1

I know the post is old, but the deque object supports already "string-buffering" if you are using joining:

>>> from collections import deque
>>> string_buffer = dequeue()
>>> string_buffer.append("a")
>>> string_buffer.append("b")
>>> "".join(string_buffer)
ab

No need to write a new class.

Comments

0

How about the string type itself?

>>> buf = ""
>>> buf += "abcdefg"
>>> buf
'abcdefg'
>>> list(buf)
['a', 'b', 'c', 'd', 'e', 'f', 'g']
>>> buf[:4] # instead of peek
'abcd'
>>> got,buf = buf[:5],buf[5:] # instead of get
>>> got
'abcde'
>>> buf
'fg'

The idiom for get() is the only thing that's noticeably ugly here.

2 Comments

That was my first thought, but I thought I'd rather use a list since strings aren't mutable.
If you're going to use a list, check out collecitons.deque instead.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.