x86 is a convoluted horror. A lot of it makes no sense except in the context of backwards compatibility, which the documentation won't necessarily point out. I highly recommend picking up a microcontroller to learn on instead of a microprocessor. Microcontrollers are mostly self-contained systems, while microprocessors are just a small piece of the picture and have complicated interfaces to the rest of the system components.
I recommend picking something in the Freescale 68HC* family. The addressing modes and instruction set are fairly clean and the architecture is simple. Something based on ARM would probably also be straightforward to learn. Don't worry about choosing a 32 bit chip, 8 or 16 bit is fine. 8 and 16 bit chips are typically simpler and will still teach you the important concepts.
Spend a couple of weeks on this and your understanding of C will be easier to come by and more thorough.
ARM, PowerPC, and MIPS are all good choices if you've got appropriate hardware to play with. All three are nice, clean RISC architectures with plenty of registers and sane addressing modes.
You should definitely learn C:
* You'll learn the memory hierarchy, which is probably the most important thing to know about performant software.
* You'll get 100x better at debugging --- both because you'll have practice, and because most of the tools you use to debug C code work for higher-level languages (gdb is still a better Ruby debugger than Ruby's own debugger).
* You'll be able to bridge Python (or Perl) to almost any library or framework you ever need.
2. In Which I Express Reservations
Don't learn assembly. In my (C and assembly-heavy) career, I've found it works in exactly the opposite direction: you won't really understand assembly until you understand C code. There are mainstream architectures (SPARC and MIPS) that are literally designed as drivers for C compilers.
You'll eventually want to be conversant in assembly so that you can debug faster (when it comes to the runtime, the C language is a flimsy abstraction indeed). But you should let your needs and interests drag you into the machine, just like you should probably learn "Stairway" and "Smoke On The Water" before mastering barre chords and sight reading --- you can have a pretty excellent punk band without ever knowing how to read music.
3. There Are Books
Everyone is going to have an opinion about K&R. What I think you need to know is, it's short and it's dry. I re-read it 6 years into my career and I was surprised at how rich it was; there's a lot of design and data structures material, beyond the core language.
There's a C book that changed my life. It's David Hanson's "C Interfaces And Implementations" (CII). I will now make a case for why it's the first and only book you'll need. You're coming to C from a high-level language. That language is giving you a couple key things you don't realize you depend on:
* Garbage collection
* Lists and hash tables
* Resizeable strings
Almost every major C project contains a site-specific reimplementation of these concepts. CII gives you one --- an internally consistent one, relatively well implemented, and extremely well documented. In doing so, it also teaches you the single most important thing about writing good C programs, which is how to build abstractions around your gnarly code.
The difference between people who know C as a language and people who can actually deliver software in it is resizeable containers (linked lists, dynamic memory allocation, high-level strings, doesn't really matter what the specific is).
The other book you want is "Advanced Programming In The Unix Environment" (or its moral equivalent, "Win32 Programming").
CII is "how". APUE is "what".
Finally, I like (for new programmers) "The Practice Of Programming".
4. What I Did To Get Started
I "knew" C for a while (maybe since I was 13) before I actually started coding in it. Two things got me unstuck.
First, I picked a couple basic Unix APIs and wrote little toy programs around them. If I remember correctly, the first thing I wrote was "who", from "getpwnam(3)", which forced me to do some basic strings and structure pointers.
Second, I wrote network code from a socket tutorial. Sockets are a great thing to get started on; just write a scraper for a service you like, and there's a zillion little problems you'll have to solve that are the same problems you solve in every other program you write.